use Exporterする時のメモ
Minilla便利だわー!って思って、モジュールを作ってみたのですが、
Exporterがよく分からなかったのでメモ。
こんな感じで、スクリプトとモジュールを配置。
. ├── aaa.pl └── lib └── Foo.pm |
“Foo.pm”はこんな感じ。
ちなみに、(caller(0))[3];
は、現在の関数名を返してくれます。
詳しくは、こちら(http://perldoc.jp/func/caller)を参照してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package Foo; use strict; use warnings; use base qw(Exporter) ; our @EXPORT = qw(foo) ; our @EXPORT_OK = qw(foo bar) ; our %EXPORT_TAGS = ( all => [ @EXPORT , @EXPORT_OK ], hoge => [ qw(hoge) ] ); sub foo { ( caller (0))[3]; } sub bar { ( caller (0))[3]; } sub hoge { ( caller (0))[3]; } sub fuga { ( caller (0))[3]; } 1; |
という訳で、”aaa.pl”を編集しながら実行してみます。
1 2 3 4 5 6 7 | use v5.12; use warnings; use Foo; say 'Foo::foo() => ' , Foo::foo(); say 'foo() => ' , foo(); |
$ perl -Ilib aaa.pl
Foo::foo() => Foo::foo
foo() => Foo::foo
これに関しては、だいたい予想通りですかね。
our @EXPORT = qw(foo);
があるので、
Foo::foo()
はもちろんのこと、foo()
だけでも動作します。
次に、以下のように変更してみます。
1 2 3 4 5 6 7 | use v5.12; use warnings; use Foo qw(bar) ; say 'Foo::foo() => ' , Foo::foo(); say 'foo() => ' , foo(); |
$ perl -Ilib aaa.pl
Foo::foo() => Foo::foo
Undefined subroutine &main::foo called at aaa.pl line 7.
この場合、use Foo qw(bar);
でインポートする関数を指定しているので、
デフォルトの動作が行われずに失敗してしまいました。
ここでデフォルトの動作???ってなると思いますが、
実は、use Foo;
とuse Foo qw(:DEFAULT);
は一緒なのです。
では、試してみましょう。
1 2 3 4 5 6 7 | use v5.12; use warnings; use Foo qw(:DEFAULT) ; say 'Foo::foo() => ' , Foo::foo(); say 'foo() => ' , foo(); |
$ perl -Ilib aaa.pl
Foo::foo() => Foo::foo
foo() => Foo::foo
ちなみに:DEFAULT
は、こんな感じで使われることがあるそうです。
1 2 3 4 5 6 7 8 | use v5.12; use warnings; use Foo qw(:DEFAULT bar) ; say 'Foo::foo() => ' , Foo::foo(); say 'foo() => ' , foo(); say 'bar() => ' , bar(); |
$ perl -Ilib aaa.pl
Foo::foo() => Foo::foo
foo() => Foo::foo
bar() => Foo::bar
foo
とbar
に関しては、
our @EXPORT_OK = qw(foo bar);
によってインポートが許可されていますが、
他はどうでしょう?
1 2 3 4 5 6 7 | use v5.12; use warnings; use Foo qw(hoge) ; say 'Foo::hoge() => ' , Foo::hoge(); say 'hoge() => ' , hoge(); |
$ perl -Ilib aaa.pl
"hoge" is not exported by the Foo module
Can't continue after import errors at aaa.pl line 4.
BEGIN failed--compilation aborted at aaa.pl line 4.
hoge()
は、@EXPORT_OK
に含まれていないためダメなようです。
ですが、これなら動きます。
1 2 3 4 5 6 7 | use v5.12; use warnings; use Foo; say 'Foo::hoge() => ' , Foo::hoge(); #say 'hoge() => ', hoge(); |
$ perl -Ilib aaa.pl
Foo::hoge() => Foo::hoge
つまり、@EXPORT_OK
を定義(宣言?)することで、
使って欲しい関数と、使って欲しくない関数を伝えることはできます。
次に、先ほどの:DEFAULT
のように、
引数を指定して関数をインポートしてみたいと思います。
1 2 3 4 5 6 7 | use v5.12; use warnings; use Foo qw(:all) ; say 'foo() => ' , foo(); say 'bar() => ' , bar(); |
$ perl -Ilib aaa.pl
foo() => Foo::foo
bar() => Foo::bar
%EXPORT_TAGS
に、all => [ @EXPORT, @EXPORT_OK ]
があるので、
:all
を指定すると、foo
とbar
がインポートできました。
@EXPORT
と@EXPORT_OK
の両方にfoo
が存在してますが、
これは問題ないそうです。
では、hoge => [ qw(hoge) ]
の方はどうでしょう?
1 2 3 4 5 6 7 | use v5.12; use warnings; use Foo qw(:hoge) ; say 'Foo::hoge() => ' , Foo::hoge(); say 'hoge() => ' , hoge(); |
$ perl -Ilib aaa.pl
"hoge" is not exported by the Foo module
Can't continue after import errors at aaa.pl line 4.
BEGIN failed--compilation aborted at aaa.pl line 4.
残念ながら、@EXPORT
、または@EXPORT_OK
に含まれていないと、
hoge => [ qw(hoge) ]
でエクスポートできないようです。
ちなみに、:DEFAULT
や:all
はタグと呼ばれており、
このタグに関連付けられた関数群のことをインポートリストと呼ぶそうです。(*1)
最後に、モジュールから一つも関数をインポートしたくない場合。
1 2 3 4 5 6 7 | use v5.12; use warnings; use Foo (); say 'Foo::foo() => ' , Foo::foo(); say 'foo() => ' , foo(); |
$ perl -Ilib aaa.pl
Foo::foo() => Foo::foo
Undefined subroutine &main::foo called at aaa.pl line 7.
今回のネタ元はこちら。
という訳で、今さら聞けないこともカジュアルに聞けちゃう勉強会、
Hokkaido.pm Casualの次の予定は6/19となっております。
詳しくは、こちら(Hokkaido Perl Mongers)をご覧下さい。
おしまい。
(*1) 続・初めてのPerl 改訂版(Amazon)より。
Leave a Comment