Exporter - 関数をエクスポートする
Exporterモジュールを使用すると、モジュールから関数をエクスポートすることができます。
# パッケージの宣言 package YourModule; # Exporterを継承 use Exporter 'import'; # エクスポートする関数を記述 our @EXPORT = qw/func1 func2/; # エクスポート可能な関数を記述 our @EXPORT_OK = qw/func3 func4/; # 関数 sub func1 { ... } sub func2 { ... } sub func3 { ... } sub func4 { ... }
Exporterを使ってモジュールを作成すると、そのモジュールをuseしたときに関数がインポートされます。
「use モジュール名;」という形でuseを実行した場合は@EXPORTに含まれる関数がインポートされます。
# @EXPORTに含まれる関数(func1とfunc2)がインポートされる。 use YourModule;
「use モジュール名 引数1 引数2 ..」という形で実行した場合は@EXPORT_OKあるいは@EXPORTに含まれ、かつ引数で指定されている関数がインポートされます。
# @EXPORT_OKあるいは@EXPORTに含まれる関数(func2とfunc3とfunc4)がインポートされる use YourModule qw/func2 func3 func4/;
@EXPORT, @EXPORT_OKはパッケージ変数です。
Exporterモジュールのエクスポートの仕組み
Exporterモジュールの仕組みについて少し解説したいと思います。まず知っておいてほしいことはuseを実行すると指定したモジュールのimportメソッドを自動的に呼び出すということです。この例ではYourModuleのimportメソッドを実行しようとします。
YourModuleにはimportメソッドは定義されていませんが、Exporterモジュールのimportメソッドをインポートしているので、Exporterのimportメソッドが呼び出されます。
Exporterのimportメソッドの中では呼び出し元のパッケージに関数をエクスポートする処理が記述されています。雰囲気が伝えることができるように@EXPORTに書かれた関数を呼び出し元のパッケージにエクスポートする処理を書いてみます。
sub import { # useの第一引数(今回の例だとYourModule) my $class = shift; # 呼び出し元のパッケージ(今回の例だとmain) my $caller = caller; # 関数のエクスポート no strict 'refs'; foreach my $func (@{"${class}::EXPORT"}) { *{"${caller}::$func"} = \&{"${class}::$func"}; } }
Exporterモジュールはどの書き方がよいの
Exporterモジュールには、複数の書き方があって次のような書き方ができます。
# その1 use Exporter 'import'; # その2 push @ISA, 'Exporter'; # その3 use base 'Exporter';
ここでは、もっとも直感的であると思われる一番目を紹介しています。