Perlでのuse宣言について
Perlをやり始めると、requireはすぐ分かるんだけれど、useって謎だなぁって思いますね!
今回は、そんなuseの謎に迫ります。
はじめに、requireは、C言語でいう%includeと同じで別ファイルにあるソースを実行時にあたかも自ソースとして読み込みます。
つぎに、useは、実行前(コンパイル時)にあたかも自ソースとして読み込みます。
実行前というのは、Perlではコマンド起動時にコンパイルしてから実行するという2段階方式になっているのです。
つまり、useはコンパイル時に実行され、requireはコンパイル後に実行されるのです。
そして、読み込んだソース(モジュール)にpackage宣言がない場合、useとrequireでは、これ以外の違いはありません。
しかし、モジュールにpackage宣言があると、ちょっとややっこしくなるのです。
まず、モジュールでなく、メインソースの方には、package宣言がありませんが、実は、デフォルトでmainというpackage名になっています。
一方、モジュールの方は、package宣言でpackage名をmain以外で指定すると、当然ですがメインソースとは別のpackage名になりますね。
しかし、別のpackage名になっても、useには他モジュールを、以下ようにあたかも自モジュール(mainモジュール)にあるようにする仕組みがあるのです。
- それは、Moduleモジュールのimportメソッドです。
- 『use Module』は、実は『BEGIN { require Module; Module->import; }』とイコールなのです。
- 『BEGIN』は、コンパイル時に実行されるブロックなのです。
- 『Module->import;』は、Moduleモジュールにあるものをmainモジュールにインポートするものなのです。
いきなり、importが出てきますが、これは、Moduleモジュール内でExporterモジュールを継承していて、Exporterモジュール内のメソッドなのです。
◆サンプル
・mainモジュール
#use Module; BEGIN { require Module; Module->import;} # use Module; と等価 print sumx(5,3),"\n"; # Moduleモジュールのsumx関数があたかも自関数のように使える
・Moduleモジュール
package Module; use base Exporter; # use Exporter; our @ISA = qw(Exporter); と等価 our @EXPORT = qw(&sumx); sub sumx { return $_[0]+$_[1]; # 渡された引数2つを加えて返す処理 } 1;
◆補足
Moduleモジュールでは、『use base Exporter』でExporterを継承して、『our @EXPORT = qw(&sumx);』でsumx関数をエクスポートしています。
mainモジュールでは、『Module->import;』でModuleモジュールでエクスポートしたsumx関数をインポートしています。