小池啓仁 ヒロヒト応援ブログ By はてな

小池啓仁(コイケヒロヒト)の動画など。

小池啓仁 ヒロヒト応援ブログ By はてな

use宣言はrequire宣言プラスExporterモジュールのimport関数?

use宣言とは、実は、BEGINサブルーチン内でのrequire宣言とExporterモジュールのimportメソッド実行と、ほぼイコールなのです。
ほぼイコールと書いたのは、importメソッドがない場合は、呼び出しはスキップされ、また、importメソッドの自作が可能だからです。
しかし、普通、Exporterモジュールを継承してそのimportメソッドを使用します。

テストサンプルソース(testx.pl)

#use testx;
BEGIN { require testx; testx->import;} # use testx; と等価
#use testx qw($Y);
BEGIN { require testx; testx->import(qw($Y));} # use testx qw($Y);と等価
print "X=$X ", \$X, "\n";
print "Y=$Y\n";
print sum(5,3),"\n";

モジュールソース(testx.pm)

package testx;
#use Exporter;
#our @ISA    = qw(Exporter);
use base Exporter;          # use Exporter; our @ISA = qw(Exporter); と等価
our @EXPORT = qw($X &sum);
our @EXPORT_OK = qw($Y);
our $X = 10;
our $Y = 20;
sub sum {
	return $_[0]+$_[1]; # 渡された引数2つを加えて返す処理
}
print "in testx.pm : X=", \$X, "\n";
1;

処理結果

C:\Documents and Settings\xxx>perl testx.pl
in testx.pm : X=SCALAR(0x1ae706c)
X=10 SCALAR(0x1ae706c)
Y=20
8

補足1(Exporter、@ISA 、@EXPORT 、@EXPORT_OK)

Exporterの使用方法

package Module;

use Exporter;
@ISA = (Exporter);
@EXPORT = qw(sub1 sub2);

ここで登場した@ISAは、配列の各要素に、パッケージのベースクラスに当たるパッケージの名前を格納します。クラスは、@ISAにある順番でメソッドの検索を行います。

上記は、「use Exporter」で、Exporterモジュールを使用することを宣言し、@ISAにExporterを代入しています。次に@EXPOERTにインクルードさせたいサブルーチンを指定しています。ここではサブルーチンの sub1 と sub2 を自動的にインクルードするように指示しています。インクルード可能にしたサブルーチンは、インクルード先でパッケージ修飾を省略して sub1() のように宣言できます。

上記のモジュールを別のスクリプトから呼び出し、sub1 を実行するには次のようになります。

use Module;

sub1();

サブルーチン名を指定しない場合には、パッケージ内で定義されている全てのサブルーチンがインポート可能になります。

@EXPORT_OKを使用すると、@EXPORTのように定義したサブルーチンが呼び出し可能になりますが、呼び出し側で明示的に指定しなければなりません。

@EXPORT_OK

package Module;

use Exporter;
@ISA = (Exporter);

@EXPORT = qw(sub1 sub2);
@EXPORT_OK = qw(sub3);

sub sub1{ print "sub1\n"; }
sub sub2{ print "sub2\n"; }
sub sub3{ print "sub3\n"; }

sub1、sub2は「use モジュール名」で自動的にインポートされますが、 sub3はインポートされません。 sub3をインポートするには、「use モジュール名 qw(sub3)」のように明示的にインポートを指定します。

# 明示的に sub3 をインポートする。
# sub1、sub2 は自動的にインポートされます。
use Module qw(sub3); 

sub3();
http://www.rfs.jp/sb/perl/04/01.html#2.モジュール

補足2(BEGINサブルーチンについて)

BEGINサブルーチンは、スクリプトコンパイル時に自動的に1回のみ呼び出されます。

http://d.hatena.ne.jp/chaichanPaPa/20071011/1192098600