4部 オブジェクト指向

パッケージとモジュール

1.パッケージ

パッケージとモジュールは、変数名やサブルーチン名の重複を防ぐために用意されている機構です。特にモジュールに関しては、他人の作成したユーティリティを簡単に再利用することができます。

パッケージの概要

変数の有効範囲としてグローバル変数ローカル変数のおさらいをしましょう。サブルーチンやブロック外にある、もしくは宣言されていない変数はすべてグローバル変数で、スクリプト内のどこでも有効です。これに対して、my宣言した変数はローカル変数となり、宣言したブロックの内側のみ有効です。

my $global = "It's getting exciting now !";
{
my $local = "Think of everything we've accomplished.";
}
print $global, "\n";
>It's getting exciting now !
print $local, "\n"; # $local は有効範囲外で利用できません!

グローバル変数はスクリプト内全域で有効なので、ブロックを気にする必要はありませんが、my宣言したローカル変数はその宣言したブロック内でだけ有効となります。この変数やサブルーチンの有効範囲である名前空間を、パッケージと呼びます。パッケージはファイルとは独立しているので、1個のファイルに複数のパッケージを入れることもできますし、複数のファイルをまたぐパッケージを作成することもできます。

スクリプト内で宣言した変数は、デフォルトで mainパッケージの一部になります。パッケージを明示的に宣言するには、package 宣言を使って次のようにします。

package pkg1;

パッケージ宣言は、デフォルトパッケージを変更します。これは、ブロック、もしくはファイルの終わりまで有効です。

package文

パッケージは任意の名前を与えて宣言することができます。その際は、package 文を使います。

パッケージ名の宣言
package pkg1; # これ以降はパッケージ名 pkg1空間

驚くほどシンプルです。この宣言がどこにもされていない場合は、デフォルトでパッケージ名が mainになっています。

簡単なパッケージ
package pkg1;
sub func{
print "OK!\n";
}
return 1;

上記パッケージをファイルとして切り出す場合は、パッケージ名と拡張子「pl」をつなげて「pkg1.pl」とします。このようにファイルにしたパッケージファイルは、実行の準備が済んだことをPerlインタプリタに知らせるために、パッケージの最後で真を返す必要があります。ここでは return 1; としていますが、省略して 1; だけでもかまいません。

パッケージを利用する

外部ファイルとして作成したパッケージを利用するには、requrie 文を使います。

require "pkg1.pl"; # ファイル名 pkg1.pl を読み込む

他のパッケージ空間にある変数やサブルーチンを呼び出す必要があるときは、パッケージ名とコロン(:)2つを、変数名やサブルーチン名の前に付け足します。たとえば、pkg1パッケージの $value を参照するには、「$pkg1::value」となります。

&pkg1::func(); # pkg1 パッケージの &func サブルーチンを利用
$pkg::value; #pkg1 パッケージの $value 変数を利用

パッケージ名なしで2つのコロンを置くと、main
パッケージの略称となります。つまり、「$::value」は「$main::value」と同じ意味になります。

パッケージの有効範囲

パッケージ名前空間の有効範囲は、package 文を宣言した場所から別のpackage文が現れるまでまでの範囲になります。

package pkg1; # パッケージ名 pkg1 の宣言
$value = "It's getting exciting now !";
package pkg2; # パッケージ名 pkg2 の宣言
print $value, "\n"; # pkg2 では $value が宣言されていないのでエラー
$pkg1::value; # 成功です。pkg1 の変数を呼び出しています
> It's getting exciting now !

特殊変数とパッケージ

$_ などの特殊変数や、STDIN、STDOUT、STDERR、ARGV、ARGVOUT、ENV、INC、SIG などの識別子は、デフォルトパッケージのmainで管理されています。ですから、mainパッケージ以外から呼び出す際も、わざわざパッケージ名を明記する必要はありません。

たとえば、パッケージ名 pkg1 から特殊変数 %ENV を参照する場合は、次のようになります。

package pkg1
sub get_script_name{
return $ENV{'SCRIPT_NAME'};
}

ローカル変数とパッケージ

myで宣言したローカル変数は、パッケージに属していません。そのような理由から、my変数をパッケージの変数として宣言することも出来ません。

下記のような代入文はエラーになります。

my $main::value = "test";
PAGE TOP


2.モジュール

パッケージを習得したら、モジュールの作成もあとほんの一歩です。モジュールはパッケージを再利用可能にしたようなもので、モジュール名と同名のファイルで定義されます。多くのモジュールはCPANから入手でき、無料で配布されています。ここではすべてを紹介できませんが、メールやFTP、データベース、テキスト処理、画像処理などの多様なモジュールが提供されています。

モジュールの概要

モジュールの利用法

モジュールは、次の方法でインクルードできます。

use モジュール名;

use文は、スクリプト実行前のコンパイル時に実行され、モジュールで定義されているサブルーチンなどをインポートします。useと似た機能としてrequireがあります。requireの場合はコンパイル時では評価されず、スクリプト実行時に評価される点が異なっています。

use文の引数に、インポートしたいサブルーチン名を指定できます。これを指定した場合は、それ以外のサブルーチンをインポートしません。

use モジュール名 qw(サブルーチン名1 サブルーチン名2);

モジュールの作成法

モジュールとは、コードを再利用する際の単位となるものです。モジュールは、パッケージ名をファイル名として、拡張子は .pm になります。モジュール内にパッケージが複数ある場合は、中心的なパッケージ名を使います。また、モジュール名は、先頭が大文字です。

たとえば、Module.pm という名前のモジュールを作成するには、次のようにpackage宣言します。

package Module;

サブルーチンをインポート可能にする

モジュールを宣言したら、今度はサブルーチンを提供する仕組みを作成します。モジュールには、サブルーチンをインポート可能にするためのExporterモジュールが用意されているので、これを利用しましょう。

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();

EXPORTのようにインポート可能にする方法があるのですから、もちろんインポート不可にする方法もあります。これは、たとえばUNIXとウインドウズの両方で利用するようなモジュールを作成するときに、UNIXだけインポートし、ウインドウズからは利用できないようにしたいときに便利です。

@EXPORT_FAIL

サブルーチンをインポート不可にするには、@EXPORT_FAIL にサブルーチン名を代入します。

package Module;
# ウインドウズならインポートしない
if ( $^0 eq 'MSWin32' ){
@EXPORT_FAIL = (sub1);
# ウインドウズ以外ならインポート
} else {
@EXPORT (sub1);
}

上記では、$^0 でOS名を調べ、ウインドウズとそれ以外のOSで処理を分岐しています。

モジュールをネストする

モジュールはネスト(入れ子)することができます。といっても、ブロックで囲んだりしてモジュールをネストするわけではありません。モジュールを設置したディレクトリに同名のサブディレクトリを作成し、そこにネストしたいサブモジュールを設置します。
たとえば、$Parent::Child::value は、Parent という名前のディレクトリにあるChildというモジュールの中にある value という名前の変数です。

BEGINサブルーチンとENDサブルーチン

スクリプトのコンパイル時に初期化するための BEGIN サブルーチンと、スクリプトの終了時に実行されるENDサブルーチンを紹介します。

BEGINサブルーチン

BEGIN サブルーチンは、スクリプトのコンパイル時に自動的に呼び出されます。このことから、BEGINサブルーチンは初期化処理に向いています。

BEGINサブルーチン

BEGIN サブルーチンは sub を省略して宣言することができます。

print $word, "\n";
BEGIN {
$word = "BEGIN!";
}

上記スクリプトを呼び出すと、 BEGIN サブルーチンを明示的に呼び出してはいませんが、print文を実行する前のスクリプトのコンパイル時に自動的に呼び出されるので、次のように出力されます。

> BEGIN!

ENDサブルーチン

END サブルーチンは、スクリプト終了前に自動的に呼び出されます。このことから、ENDサブルーチンは終了処理に向いています。END サブルーチンは、dieで終了した場合でも呼び出されますが、異常終了したときなどは実行されないので、注意してください。

ENDサブルーチン
END {
print "END!";
}

関連記事