Perlのモジュールを使えるようになったのが、
一年半ぐらいまえ。
だけど、すごくあやふやなまま騙し騙し使っていた。
使っているうちに、あやふやな部分がだいぶクリアになってきたので、
書いておく。
Perlのモジュールを使うということは、
「use なんとか」って書くことなんだけど、
誰しも使う最初の「use なんとか」は、おそらく「use strict」でしょう。
だけど、このuse strictは全然普通のモジュールっぽくないし、
実際、モジュールではないのかもしれない。
なんで、モジュールっぽくないかと言うと、
それをuseすることで、なんらかのサブルーチンが
使えるようになるわけではないから。
で、use strict の次に使うモジュールって何かなと考えたら、
もしかしたら「use Data::Dumper」かもしれない。
Perlの初心者が上達してくると、
無名ハッシュや無名配列を覚えて、
そしてそれらを何回も組み合わせて複雑な構造体のようなものを作れるように
なってくる。
そうすると、こんがらがった無名ハッシュ無名配列の構造を
一度に全部吐き出して、俯瞰して見られるようにしたい
という衝動に駆られる。
その衝動に応えてくれるのが、
Data::Dumperである。
このモジュールは、「use Data::Dumper」と書いて、
print Dumper( $struct_ref )
という感じで書けばすぐ使えるので、
モジュールを初めて使う人にも結構とっつきやすいと思う。
これで組み込みモジュールの便利さに味を占めると、
どんどん便利なモジュールを発掘しては
見よう見まねで使うようになって、
そのうち自分でもモジュールを作りたいと思うようになる。
でも、自分で作りたいと思っても、
結構そこでつまづく人が多いのではないかな。
少なくとも僕はそうで、
便利なモジュールにたくさん触れて、
便利さだけでなく、ソースコードの可読性を上げるためにも
独自モジュールを作って、
雑多なサブルーチンをメインのソースコードの外側に
置きたくなる。
だけど、そのためにはどうすればよいかというのが
案外わからないものなのである。
モジュールを自分で作る上でのポイントを箇条書きしてみる。
拡張子は .pm にする
ファイルの先頭に #! /usr/bin/perl というおまじないはいらない
モジュールとそれを呼び出すスクリプトの位置関係をどう指定するか
pmファイルはサブルーチンの単なる寄せ集めの場合とオブジェクト指向プログラミングにおけるクラスに相当する場合の2つがある
ファイル名とパッケージ名の一致
サブルーチンを呼び出すときに、パッケージ名を端折って呼ぶには?
モジュールの最後は「1;」と書くべし
と、こんな感じだろうか。
けっこういろいろと注意すべき点があって、
ちょろちょろっとpmファイルを書いてみて、
そこに書いたサブルーチンを呼び出そうとしてみても、
呼び出すスクリプトとの相対位置がまちがってるとか、
パッケージ名をつけ忘れているとか、
パッケージ名とファイル名が厳密に一致してないとか、
そういう些細な問題で動かなかったりして、
原因がわからないものだから、
自分の知らないもっと高度な知識が必要なんだろうと思って
諦めてしまう場合が多いと思う。
エラーメッセージをきちんと読めば、
なんで止まってしまうのかきちんとわかるはずなんだけれども。
僕はそんな感じで、何度も挫折してはリトライを繰り返した。
その過程で、例えば「use lib 'lib'」という文の意味に気付いて行ったりする。
モジュールとそれを呼び出すスクリプトとの位置関係。
もしスクリプトとモジュールが同じフォルダの中にある場合は上記はいらないが、
スクリプトの置いてあるフォルダに、「lib」というフォルダを作り、
そこにモジュールを入れる場合は必要となる。
オブジェクティブなモジュールにするには、
newという言葉や、
bless というperlの関数を理解したり、
オブジェクトを作ってそのメソッドを呼び出すときの
「my $obj = Module->new」とか、
「$obj->methodName( @arg )」というような
記法を身につけていないと厳しい。
僕がつい最近理解したのが、
「use Encode 'decode', 'encode', 'encode_utf8';」という書き方である。
これはこんな風にも書いて良い。
「use Encode qw(decode encode encode_utf8)」
こうすると何が嬉しいかというと、
単に「decode( $str )」と書くだけでメソッド(サブルーチン)が使えることである。
もし、「use Encode」とだけ書いたとしたら、
「Encode::decode( $str )」と書く必要がある。
わかってしまえば簡単なのだが、
理解ができたときに、目からうろこだった。
最初の方で書いた「use Data::Dumper」は、そのあとに何も書かなくても、
いきなり「Dumper( $ref )」と書けば実行されるので、
初期の頃の体験に支配されていたのだと思う。
そんでもって、EncodeとData::Dumperの違いは何なのか考えて、
「use Exporter」モジュールを使うことに気付いたのであった。
これまで他人のソースコードの中で幾度となく目にしてきたことが
やっと理解できるようになってきた、ところである。
で、この辺りのことと閉口して文字コードのこともわかってきたのだが、
それについては次回。