.pm 散策をすると、入門書には書いてない use の使い方がたくさんでてきます。man perlfunc をてがかりに use の正しい使い方について勉強しましょう。man perlfunc で引くと次のように use の記法の4つのバリエーションが書いてあります。
use Module LIST use Module use Module VERSION LIST use VERSION
use Module LIST が一般的な使い方です。これば次のような文と同じことになります。
BEGIN { require Module; import Module LIST; }
上の文では、先ず Module を読み込んだ後、import 関数に Module LIST が渡されて実行されます。import 関数は組み込みの関数ではなく、Module 側で記述しなければなりません。テスト用に次のモジュールを Use_sample.pm という名前で作成します。
package Use_sample; sub import { my $package = shift; my $a = shift; $a = ( $a ? $a : 'hello' ); ${"${$package}::imported"} = $a; } 1;
簡単に説明すると、import 関数の$packageには、use を使って Use_sample.pm を呼び出した側のパッケージのパッケージ名が入ります。$a は use Use_sample LIST; と記述されたときのリスト(この例では引数が1個の場合を想定しているのでスカラーになります)の値です。$a に引数が渡されていれば $a のまま、引数がない場合は $a = 'hello' となります。
use Module LIST という呼び出し方をすると、Module の import 関数に LIST が引き渡されます。次のようなテストプログラムを test_use_2.pl と言う名前で作成します。
#!/usr/bin/perl use Use_sample 'Hi'; print "$imported\n";
test_use_2.pl を走らせると 'Hi' が import 関数に引き渡され $imported 変数の値が 'Hi' になって表示されます。
$ perl test_use_2.pl Hi
つぎに import 関数に引数を渡さない test_use_1.pl スクリプトを作成します。
#!/usr/bin/perl use Use_sample; print "$imported\n";
test_use_1.pl では、import 関数に引数が渡されないので $imported の値は 'hello' になります。
$ perl test_use_1.pl hello
Module を読み込んでも import 関数を動かしたくない場合は、明示的に use Module(); とします。次の test_use_0.pl がその例です。
#!/usr/bin/perl use Use_sample(); print "$imported\n";
この場合 import 関数が呼び出されないので $import は空になります。
$ perl test_use_0.pl
例として、標準パッケージの vars のコード部分は次のようになります。
package vars; require 5.002; # The following require can't be removed during maintenance # releases, sadly, because of the risk of buggy code that does # require Carp; Carp::croak "..."; without brackets dying # if Carp hasn't been loaded in earlier compile time. :-( # We'll let those bugs get found on the development track. require Carp if $] < 5.00450; sub import { my $callpack = caller; my ($pack, @imports, $sym, $ch) = @_; foreach $sym (@imports) { if ($sym =~ /::/) { require Carp; Carp::croak("Can't declare another package's variables"); } ($ch, $sym) = unpack('a1a*', $sym); *{"${callpack}::$sym"} = ( $ch eq "\$" ? \$ {"${callpack}::$sym"} : $ch eq "\@" ? \@ {"${callpack}::$sym"} : $ch eq "\%" ? \% {"${callpack}::$sym"} : $ch eq "\*" ? \* {"${callpack}::$sym"} : $ch eq "\&" ? \& {"${callpack}::$sym"} : do { require Carp; Carp::croak("'$ch$sym' is not a valid variable name\n"); }); } }; 1;
vars.pm では import メソッドだけが記述されています。したがって、グローバル変数を導入する use vars <変数のリスト> というのは組み込みの関数ではなくて、普通に use を使ってモジュールを導入しただけだということが分かります。
use の最初の引数がモジュール名ではなくて Perl のバージョンナンバーの場合、そのパッケージを利用する Perl のバージョンがそれより旧い場合はエラーメッセージが出てスクリプトの実行が強制終了されます。
use 5.003_90;
また use Module VERSION LIST と、Module と LIST の間にバージョンナンバーが入っている場合、use は Module の VERSION メソッドにバージョンナンバーを渡して実行します。デフォールトでは Module の $Module::VERSION 番号よりバージョンナンバーが大きかった場合、プログラムはエラーとなって強制終了されます。