PerlのPackage 作り方

2011.05.16 1:09
 久々にPerlです。久しぶりに見るとPerlの変態的な性格がよく表れているよい言語で自分に合っていることがわかります。
さて、Packageなのですが、久々にPerlに戻ったのはMTのPluginを作り始めたからです。ここではどうしてもモジュールを組み込む必要があるし、何せ完全オブジェクト指向なので久々にコードみるといろいろ忘れているわけです。PHPからPerlに戻ると、変数の宣言もいろいろだし、phpにあるのかないのかわからんのですが、レキシカルスコープっていうのを全然使っていなかったのでその復習です。

 Packageが何であるかというのは他のサイト様にお任せすることにして、ここではその書き方の復習だけにします。PHPからこっちへ来るとちょっと違った概念なのは、(というのもPHPの方がちょっと特殊なのだと思いますが...)変数という時には、いわゆるサブルーチンも変数として扱うってことです。要するにパラメーターのある変数というわけでして、変数の扱いと殆ど同じということになります。変数<=>サブルーチンという区別は、変数・関数という区別とちょっと違うという感じがします。
 さてPackageで名前空間を分けるということをするのですが、あのイヤラシイ「Packageの名前空間が有効なのは、次のPackage宣言が行われるまで」というのは、私的には結構気持ちが悪いのでやめておきます。Packageはブロックで作るようにした方が実に明快です。
{ package Foo;
  $var = 'オムニオ';
  1;
}
これが一番綺麗だと思うわけですが、習慣的にPackageは結局のところモジュールになっちゃうわけで、1つのファイルに1つの名前空間ということで、Package宣言したら1で終わりましょうということでいいんじゃないでしょうか。
package Foo;
$var = 'オムニオ';
1;
Perlはサブルーチンをファイルの後ろに書きます。PHPは前に書きます。Cは前に書きます。皆足並み揃えてほしいわけですが、バラバラです。Perlはサブルーチンを後ろに書いてもちゃんと動きますが、変数を後ろに書いたのでは機能しませんので、Packageもメインスクリプトの前に書くということになってしまいます。
世の中のプログラマーには「なんでこんなことすんの?」という不思議な質問も存在します。Webデザインに近いPHPプログラマーにはそう人がいます。しかし、変態なプログラマーは、この名前空間に合理性とすばらしさを見出し、最終的には自分で各コードが異常に少なくなって気がつくと昔やっていたプラモデルのようにパーツを組み立てているということになってしまっています。
 モジュールではない単にPackageファイルは、通常の別ファイルとしてrequireすると読み込めます。
index.cgi
#!/usr/bin/perl
require("package.pl");

print "Content-type: text/html\n\n";

$re = &foo::test("オムニオ");
print $re."<br />\n";
print $foo::var."<br />\n";

exit;

package.pl
package foo;
$var = 'パッケージテスト';
sub test {
    my($text_var) = @_;
    return $text_var;
}

1;

結果
オムニオ
パッケージテスト
というようになります。呼び出す時は::というPerl特有の記号を使って通常の変数やサブルーチンのようにして呼び出します。
&<Packageの名前空間>::<サブルーチン>();
$<Packageの名前空間>::<変数>;
です。&はあってもなくてもいいのですが、あった方が昔風で私は好きです。なぜなら、
&サブルーチン
$スカラー変数
@配列
%ハッシュ
と昔から決まっているからです。&を抜いてしまうとJavascriptとPHPが混じったみたいな変な感じがするのでよろしくないです。
しかしこれは全然モジュール(かもしれないけど)、けっしてモジュールではなく、オブジェクト指向でもありません。単に名前空間が新たに作成されたに過ぎません。しかし実際問題、これだけの名前空間わけで殆ど無数の変数が作成可能なので、かなり大きなアプリケーションを作ることもできます。
 Perlは親切なのか不親切なのか、こういったプログラムの構造抽象度の度合いが、
ライブラリー -> パッケージ -> モジュール -> オブジェクト
みたいな感じになってます。これ、実は本来的な意味では全然違います。専門的にみれば全然違います。モジュールはすでにオブジェクト指向を含んでいる場合もあるし、ライブラリーはパッケージかもしれません。しかしだいたい要約するとこんな感じになるということです。

パッケージの初期化

 実際に使ってみないとパッケージの初期化なんて全く意味がわからないということになりがちですが、プログラムが複雑化してくると初期化は必要になってきます。特に複数人で開発していると、どんなでもないパラメーターをがんがん送り込んでくるという始末になるし、最低限必要とされるパラメーターが来ない可能性もある。そういう場合には、何とか最低限動くものを...ということで、初期化してデフォルトの値なんかを放りこんでやるというわけです。BEGINはpackageの一番最初に処理されるので、明示的に初期化ができます。(Perlは単純に上から順番に処理してゆく性格なので、特にBEGINがなくてもいい時も往々にしてあります。)
 








プロフィール



  • Name :: 山上オサム ♂(39)
  • Hobby :: 武術
  • Work :: Web Designer