そろそろPerl4に関して一言いっとくか(クラシカルPerl入門)
仕事でPerlを使うことになり、先週から久々に(本格的に)使ってみました。大体プログラミング言語なんてものは特殊なやつを除けばどれも根本は同じなので、それ自体で詰まるということはありません。
が、10数年ぶりのPerlを使いながら、懐かしいことを思い出してみました。思えば遠くへ来たものだ。
my!our!
Perl4では、my*1だとかありませんし、our*2ももちろんありません。
当然ながら、localを使います。
myはまさにレキシカルスコープ、ourはパッケージローカルな変数となります。で、Perl4に存在した(というか、今も存在しますが)localというのは、特殊なグローバル変数。その時点でグローバル変数の値を置き換えてしまい、ブロックを出た後でグローバル変数の値を戻します。つまり、以下では、test2()の中で$aが10ではなく1なのですね。myによる宣言とは意味が異なります。
$a = 10; sub test { local $a = 1; test2(); } sub test2 { print $a; # 10 or 1? }
なお、localを使う意味はほぼ既にありません。
型グロブ
Perlにはグロブというものが二種類あり、一つがファイル名グロブ*3で、もう一つが型グロブです。
型グロブというのは、普通に生きている我々は使わないのですが、特殊な用途で利用します。Perlで使う変数やサブルーチンなどは総称して「シンボル」と呼ばれますが、この「シンボル」を統合して使うのが型グロブです。
何を言っているのかわからないかもしれませんが、簡単に言えば、$a、@a、%a、&aといったものを統合して*aとして指す機能が型グロブです。
それで何ができるのかといえば大したことができるわけではないのですが、Perl4ではたまに用途がありました。その一つが「ファイルハンドルの変数化」です。
ファイルハンドルは、何も考えずに使うとグローバルとなります。
open(FILE, "file.txt"); # このFILEはプログラム全体で参照可能。
これが非常にうざいわけです。例えばローカル化したり、サブルーチンの引数に渡したりしたいわけです。
しかし、このFILEは変数ではありません。
しかし、型グロブ*FILEを使うと、このFILEというファイルハンドルを変数のように使うことができます。
local *FILE; # FILEを局所化 open(FILE, "file.txt"); sub test{ local(*FILE) = shift; # 変数のように使える。 while(<FILE>){ print; } }
なお、仮に$FILEとか@FILEといったものが別個に存在した場合、*FILEによって巻き添えにされますのでご注意。
今なら、ファイルハンドルはモジュール経由で扱うことができます。
フォーマット文
Perl4でどうのという話ではありませんが、昨今のPerlであまり見かけない機能。確か昔は「はじめてのPerl」でも紹介されていた機能です。
$name = "Yamada"; $age = 30; write REPORT; format REPORT |@<<<<<<<<< | @>>| $name, $age .
これによって、上で言えば$nameと$ageの内容を|Yamada | 30| のように整形して出力することができます。
なぜ使われないかといえば、formatで参照される変数は、グローバルである必要があるため。(ourやらlocalならば可ですが、myだとダメですね。)なお、formlineって機能がありますが、これも使われているのを見たことないですね。
dbmopen
最近は、ファイルDB(BarkleyDBなど)を直接に扱うことも少ないのかもしれません。が、tie*4を使って、DBとハッシュを結びつけるという手法があります。
ですが、Perl4ではdbmopen()を使います。はじめてのPerlでも使ってましたね。
dbmopen(%MYDB,'dir/dbfile',0666);
こうやって、DBに結びつけたハッシュを使います。ちなみに、閉じるときはdbmclose()があります。
今では使う意味がありません。
シンボリックリファレンス
リファレンスを使うのはPerl5では当然。しかしPerl4にはそのようなしゃれたものはありませんでした。
しかし、こんなことはできます。
$a = "abc"; $abc = "xyz"; print ${$a}; # これが print $abc; として働く
これがシンボリックリファレンス、あるいはソフトリファレンスです。皆様がPerl5で使っているものがハードリファレンス。
既に、使う意味は全くないといえるでしょう。use strict;すると使えませんし。
ハードリファレンスがないということは、矢印演算子もありません。
chop
chomp() によって、行末改行文字を切り取るのはよく使う機能の一つですが、これもPerl5から。Perl4ではchop()を使って、行末の1文字を切り取ります。
map
Perl4にはmap関数もありませんでした…。ですので、配列の置き換えはforeachなどを使っていました。
モジュール
そもそもモジュール自体ありませんでした。ですので、useすることもありません。requireによって他のコードを取り込むことはできました。
CPANからモジュールを引っ張ってきて簡単に機能が増やせるようになったのもPerl5のおかげ。
論理演算子
「かつ」や「または」といったものに、and/or/notを使えるのもPerl5から。Perl4では&&と||と!です。
とはいえ、Perl5でPerl4風の書き方が使われなくなったわけではありません。andと&&は結合の強さが違うので注意(他も同様)。