Perl/CGI研究室 'PERL-LABO'

Perl/CGI研究室 'PERL-LABO' TOPへ
戻る(History.Back)

パッケージの研究

研究内容

前回作ったライブラリをパッケージにします。 パッケージの作り方、使い方を研究します。

詳細

パッケージって?

ライブラリっていうのは、関数を集めたものっていうことでした。 それをパッケージにするっていうのはどういうこと? パッケージってなに?ということですが、 パッケージっていうのは、ライブラリに名前を付けたもの、と言えるでしょうか。 名前を付けるということは、名前によってライブラリを区別しようっていうことですね。

関数には必ず関数名が必要です。 関数名は基本的に自由に付けることができますが、制約もありました。 それは、他の関数とか変数とかと重ならないような新しい名前をつけなくちゃいけない、 ということでした。 これ、結構困るんです。なんでかっていうと、 例えば require でライブラリファイルを読み込んだとき、 そのライブラリで使われている関数名と同じ名前の関数を作ることができないんです。 作らなきゃいいじゃん?とも思えますが、作った後だったら? プログラム完成間近になってから、なにかライブラリが使いたくなって require したら、そのライブラリに既に作成済みの関数と同名の関数が存在していたら…。 そしたら、エラーになってプログラムが動かなくなっちゃいます。

自分が作ったライブラリなら、それほど心配しなくてもいいかも知れません。 でもライブラリって凄いんですよ!すごく便利なライブラリは、 インターネットで無料で配布されていたりします。 すごく便利なライブラリがあったら、使わせてもらいたいですよね。 そういうときは、ライブラリの中になんていう関数があるのか全部理解してるわけじゃ ありませんし、関数名の衝突が起こる確率も高くなりますね。 自分が作ったライブラリと、貰ったライブラリの中で関数名が衝突したとしたら、 やっぱりこれもエラーです。そんなことになったら、困っちゃいますよ。

そんな困った事態を回避するために、パッケージというものがあります。 ライブラリに名前をつけて、区別するんです。 例えば、自分のライブラリにhogeっていう関数があったとしましょう。 貰ったライブラリの中にもhogeっていう関数があったとしましょう。 こんなとき、ライブラリにそれぞれ、俺パッケージ、貰ったパッケージ、という名前が付いていれば、 俺hoge、貰ったhoge、というようにその中にある関数も区別することができるようになります。 パッケージにすると関数名や変数名の衝突エラーを未然に防ぐことが出来るんですね。 ですので、ライブラリを作ったら、名前を付けてパッケージとしておくわけです。

結果

パッケージの作り方

ライブラリをパッケージにするって、なんだか難しそうだと思ったら実は簡単でした。 ライブラリファイルの先頭に、次のような1行を入れるだけなんです。

package パッケージ名;

これだけで、ライブラリがパッケージになります。なんだ簡単! パッケージ名は半角英数字で自由に付けることができます。

管理人が作ったライブラリの名前は…

さて前回作った getformdata.pl ですが、なんていうパッケージにしようかなぁ…。 関数名とかは、関数の機能が分かるような名前にするのが普通です。 変数名も、なんに使われるのか、なにが入っているのか分かるような名前にするのが普通ですね。 パッケージも、どんな関数が入っているのかっていうことが分かるような名前にすべきでしょうか。 いや、パッケージの目的は、関数名の衝突を避けるためでした。 なので、パッケージ名は基本的に他の人と重ならないようなものにすべきですね。 ということで、作者の名前とかにしたらいいんじゃないかと管理人は思いました。 さらに、どんな関数が入っているのか分かるようにするなら、 その後ろにそのライブラリの意味を表す言葉を付けたらいいですよね。 管理人はそこまでやる必要は無いと思いますけど人それぞれの好みかも知れませんね。

さて、パッケージ名、決めました!このサイトのサイト名、PERL-LABO。ですから、 perllaboパッケージ。うーんちょっと長いかなぁ。 パッケージ名はあんまり長いと後で不便なんですよね。 ちょっと縮めて、plaboパッケージ。 もうちょっと縮めて、plabパッケージ。うんこれにしよう。 これに決めます!plabパッケージです。

複数のライブラリに同じパッケージ名もOK

複数のライブラリに同じパッケージ名をつけてもOKです。 ですから、パッケージというのは、名前の付いた、ライブラリの集まり、とも言えますね。

ということで、管理人がこれから作るライブラリは全部 plabパッケージの中のライブラリになります。

パッケージ内の関数の呼び方

ライブラリに名前が付いて、関数の呼び出し方が変わります。 関数名の前に、パッケージ名が付きます。

パッケージ名::関数名()

このように、パッケージ内の関数には常にパッケージ名を付けることになりますので、 あんまり長いパッケージ名だと入力するのが面倒だし、プログラムがごちゃごちゃして 読みにくくなったりするんです。パッケージ名は短めがいいですね。

あ、ここまでPerlのバージョンについてまったく触れてませんでした。 この「パッケージ名::関数名」という呼び出し方は、Perl5以降で使えるものなんだそうです。 (うーんバージョンによって呼び出し方が違うっていうのは嫌だなぁ。どうしてだろう?)

作成したCGIプログラム

getformdatatest.cgi
#!/usr/bin/perl

require 'getformdata.pl';

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

$formdata = plab::getformdata();
print "formdata : $formdata";
getformdata.pl
package plab;

sub getformdata
{
	local $formdata;
	if ($ENV{'REQUEST_METHOD'} eq "GET") {
		$formdata = $ENV{'QUERY_STRING'};
	}
	else {
		read(STDIN, $formdata, $ENV{'CONTENT_LENGTH'});
	}
	return $formdata;
}

1;

実行結果

下の入力ボックスに文字列を入力して、送信ボタンを押してください。 別窓が開きます。

考察

これで安心

これで、将来、関数名の衝突が起きて困るとか、特に、変数名の衝突が起きて、 原因不明のエラーに苦しむとか、そういうことが起きなくなります。 保険のようなものですが、これで安心、ですね。

なんか嬉しい

自分で作った関数とか、自分が作ったライブラリとかも、なんだか嬉しかったんですが、 自分が作ったパッケージっていうのもやっぱりなんだか嬉しいです。 もしかして、いつか将来、plabパッケージが世界に羽ばたいたり…しないだろうけど。

分かったこと

  1. 関数名、変数名の衝突を防ぐためにライブラリはパッケージにしておきます。
  2. パッケージは、ライブラリファイルの先頭で package パッケージ名; として宣言します。
  3. パッケージ内の関数を呼び出すには、パッケージ名::関数名()とします。
    ただしPerl5の場合です。Perl4の場合は パッケージ名'関数名 となるらしいです。
Perl/CGI研究室 'PERL-LABO' TOPへ
戻る(History.Back)

Copyright (c) 'PERL-LABO' All Rights Reserved.  リンクフリーです。