Perl Perl_6
Perl モジュール Exporter 02 基本 @EXPORT @EXPORT_OK (d091)
目次 - Perl Index
Theme
Perl について、復習を兼ねて断片的な情報を掲載して行く連載その d091 回。
Perl で、サブルーチンを呼び出し元にエクスポートするためのモジュール「 Exporter 」を確認する。
今回は、「 Exporter 」の使い方とエクスポートする対象を管理する Exporter の配列「 @EXPORT 」と「@EXPORT_OK 」を確認します。
サブルーチン「 import() 」
(d089) で確認したとおり、Perl の「 use 」は内部的にサブルーチン「 import() 」を呼び出しています。
use Module List;
# exactly equivalent to
BEGIN {
require Module;
Module->import( LIST );
}
これにより、モジュール「 Module 」側で定義されたサブルーチン「 import() 」を通じて引数「 LIST 」の名前 ( シンボル ) を持った機能が現在のプログラム ( の名前空間 ) にインポートされます。
NOTE: Module 側で import() が定義されていない場合、import() の呼び出しはスキップされます ( たとえ AUTOLOAD (d086) が定義されていたとしても )。
しかし、実際には「 import() 」を独自実装することはまれで、代わりにより高機能で確実なモジュール「 Exporter 」を使います。
モジュール「 Exporter 」
モジュール「 Exporter 」は高機能な「 import() 」を実装した Perl のコアモジュールで、機能のエクスポート ( 利用者側からいえばインポート ) の設定や管理を行うことができます。
つまり、「 Implements default import method for modules 」( モジュールのためのデフォルトの import メソッドの実装 ) です。
Exporter のドキュメントは (d090) で確認しました。
今回はその中から、特別な配列「 @EXPORT 」と「 @EXPORT_OK 」を確認します。
Exporter の使い方
自作のモジュール ( ここでは YourModule ) で、モジュール「 Exporter 」を使う方法はいくつかあります ( TMTOWTDI )。
まず、ドキュメントの SYNOPSIS ( 概要 ) にある方法です。
package YourModule;
use strict;
use warnings;
require Expoter;
our @ISA = qw(Expoter);
our @EXPORT_OK = qw(munge frobnicate);
これは、(d000) で確認した「 require 」に裸の単語 ( bareword ) でモジュール名を指定する方法です。
なお、Good Practices にあるように、プラグマ「 strict 」(0x35) および「 warnings 」(0x15) と併用する場合、パッケージグローバルな変数である「 @ISA 」や「 @EXPORT_OK 」にはキーワード「 our 」が必要です。
モジュール ( パッケージ からなる クラス ) を継承するための特別な配列「 @ISA 」については (d069) で確認しました。
次のように「 use 」を使う方法もあります。
package YourModule;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT_OK = qw(munge frobnicate);
ここでは、Exporter が実装している「 import() 」の利用を明示的に指定しています。
(d069) で確認したモジュール「 parent 」を利用して Exporter を継承する方法もあります。
package YourModule:
use strict;
use warnings;
use parent qw(Exporter);
our @EXPORT_OK = qw(munge frobnicate);
モジュール「 base 」も同様に利用可能ですが、2017 現在ではより簡易な「 parent 」が主流だと理解しています。
なお、「 @ISA 」や「 use parent 」による手法では Exporter を *継承* するので、Exporter で定義されている import() を特に指定することなく利用できます。
配列「 @EXPORT 」
Exporter が持っている特別な配列「 @EXPORT 」には、デフォルトでエクスポートしたいシンボル ( 機能の名前 ) をセットします。
our @EXPORT = qw( afunc bfunc );
ここでは、サブルーチン「 afunc() 」と「 bfunc() 」をエクスポートするように指定しています。サブルーチンのシジル「 & 」は不要です。
なお Exporter は、サブルーチンに限らずスカラ, 配列, ハッシュ, 型グロブのエクスポートも可能ですが、時にそれらは忌々しく解決が困難な問題を引き起こすので、基本的にはサブルーチン以外はエクスポートすべきではないそうです ( What Not to Export )。
「 @EXPORT 」の利用
配列「 @EXPORT 」にセットしたシンボルは、モジュールを use したプログラムの名前空間へデフォルトでエクスポートされます。
その動作の確認には、次のコード「 People.pm 」を使います。
package People;
use strict;
use warnings;
# Exporter を継承
use parent qw(Exporter);
# デフォルトのシンボルをセット
our @EXPORT = qw(set_name get_name);
my $atr = {Name => 'anonimous'};
# 名前をセットするサブルーチン
sub set_name {
my $name = shift;
$atr->{Name} = $name;
}
# 名前をゲットするサブルーチン
sub get_name {
$atr->{Name};
}
7 行目で Exporter を継承し、10 行目で @EXPORT にシンボル ( サブルーチン名 ) をセットしています。
このコードを利用するのは、次のコードです。
# People.pm を use
use People;
# People のサブルーチンを利用する
# ゲット
my $name = get_name();
print "That name is $name\n";
# セット
set_name('Bellri');
# ゲット
my $new_name = get_name();
print "That new name is $new_name\n";
@EXPORT はデフォルトでシンボルをエクスポート ( 利用者側にはインポート ) するので、7 行目で People.pm を use するだけでサブルーチン「 set_name() 」と「 get_name() 」が利用可能です。
しかしながら、Selecting What to Export で言及されているとおり、「 特に良い理由もなく何かをデフォルトでエクスポート 」することは悪しきこととされています ( Do not export anything else by default without a good reason! )。
ですから、もし何かのシンボルをエクスポートしたい場合は、この「 @EXPORT 」ではなく次の「 @EXPORT_OK 」を利用します。
配列「 @EXPORT_OK 」
配列「 @EXPORT_OK 」の使い方は「 @EXPORT 」とほぼ同じです。
# @EXPORT の代わりに @EXPORT_OK
#our @EXPORT = qw(set_name get_name);
our @EXPORT_OK = qw(set_name get_name);
異なるのは、利用者側のプログラムでの扱いで、利用するシンボルを明示的にリストしなければなりません。
# シンボルを要求
use People qw( set_name get_name );
# People のサブルーチンを利用する
# ゲット
my $name = get_name();
print "That name is $name\n";
# セット
set_name('Bellri');
# ゲット
my $new_name = get_name();
print "That new name is $new_name\n";
つまり、@EXPORT_OK にセットされたシンボルは「 エクスポートの準備は OK 」な状態におかれ、必要に応じて名前を指定して利用することになります。
当然、シンボルを要求しなければその名前を使うことはできません。
反対にいえば、シンボルの要求さえしなければ、モジュールを使うユーザの名前空間を汚染することはないということです。
エクスポートするべきでないもの
What Not to Export では「 エクスポートするべきはないもの 」が解説されています。
まず第 1 に次のものが挙げられます。
・メソッド名
オブジェクト志向では blessed ref を通じてメソッドを利用するので、Exporter でシンボル ( メソッド名 ) をエクスポートする必要はありません。
・デフォルトでの何か
Exporter ( の import() ) によるエクスポートは、インポートする側の名前空間空間を汚染するので、一般にデフォルトで ( 暗黙的に ) 何かをエクスポートすることはすべきではないとされています。
ですから、どうしても何かのシンボルをエクスポートしたい場合は、@EXPORT ではなく @EXPORT_OK を利用します。
・あなたが必要としないもの
特に理由がないのであれば、なにもエクスポートしないことが良いことだそうです ( less is more )。
それから、次の項目も重要です。
・変数名
(d089) で確認した通り、Exporter ( import() ) は変数名をエクスポートすることが可能です。
しかし、それは *追跡と解決が困難な問題* を引き起こす元になるのでやるべきではないと戒められています。
できるからといって、それがやって良いこととは限らないということです。
NEXT
次回は、エクスポートする複数のシンボルをひとまとめにできる「 %EXPORT_TAGS 」を確認します。
参考情報は書籍「 続・初めての Perl 改訂版 」, 「 Effective Perl 第 2 版 」を中心に perldoc, Wikipedia および各 Web サイト。それと詳しい先輩。
目次 - Perl Index
Perl mp2 翻訳 Web コンテンツ圧縮の FAQ (d228)
Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227)
Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226)
Perl mp2 翻訳 テンプレートシステムの選択 (d225)
Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224)
Perl mp2 翻訳 チュートリアル (d223)
Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227)
Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226)
Perl mp2 翻訳 テンプレートシステムの選択 (d225)
Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224)
Perl mp2 翻訳 チュートリアル (d223)