「なんとなくメモ」に書きっぱなしにしておくのもなんなので。
require 文で呼ばれるファイルは、末尾で評価された式が真でなくてはならない。 ファイルの尻に 1; とか書いておくこと。
=>
演算子
演算子 =>
は ,
(カンマ) と同じ意味。
ハッシュをリテラル形式で書きたいときに使うと良い。
%somehash = ( time=>'tashiro', onigiri=>'washo-i' );
などと使うと見易くなるかもしれない。
ハッシュのキーは、基本的にはクォートで囲んでも囲まなくても同じなのだが、
キーの頭文字が数字の場合は囲む必要がある。常に囲っておくという方法もあるが、
=>
演算子を使ったときの見易さの向上度合いが低いのが難点。
$hoge =~ /^(x{3,10})/;
($hoge
の先頭から、3 個ないし 10 個、文字 'x' が連続している)
というマッチで、"3," と "10" の間にスペースを入れてはいけない。
my で宣言された変数のスコープは、その時点の package 内のみに限定される。
たとえば、package 宣言を含むファイルを require して、
その中の変数を $packagename::variable
という具合に参照する場合、
変数が my variable;
と宣言されているとハマる。
この場合は、(もちろん、require されているファイル内の)宣言の my を外す。
use strict;
としている場合、これも外なければならないが仕方がない。
qq(hoge)
は "hoge"
と等価だが、
" をエスケープせずに済むので、HTML を吐かせる時なんかは便利。
print qq(<tr><th abbr="number">数</th><th abbr="OS">OS</th><th abbr="\%">割合</th></tr>\n);
ここで ()
は、||
、//
なんかでも構わない。
つまり、qq
は、直後の 1 文字を " の代わりにして文字列を記述するために使われる。
ただし、(), <>, {}, [] は 2 つで 1 対にして使われる。
また、スペース、_(アンダーバー)、アルファベット、数字は使えない。
よく使われる記号は /, |, :, ! あたりかな ?
もちろん、" の「代わり」にするだけなので、qq|〜|
等とした場合に、
〜 の中に "|" が含まれるならエスケープしなければならない。
また、変数展開も有効であるため、"%" が含まれる場合も同様にエスケープする。
同様のことを 'hoge'
に対して行いたい場合は、q(hoge)
とする。
jcode.pl では、ファイルの頭の方で
$rcsid = q$Id: jcode.pl,v …… $;
とかやってました。
# 上手くいかないコード
($hensu1, $hensu2, $hensu3) = ('foo', '', 'bar');
@sr_list = ('hensu1', 'hensu2', 'hensu3');
foreach (@sr_list) {
if (!$$_) {
my $rs = sub { print "$_ が空です.\n" }; # ここで $_ を使ってるのがマズい ?
push(@error_list, $rs);
}
}
foreach (@error_list) {
&$_();
}
シンボリックリファレンスを用いて、変数が空だったら、 その旨を表示するサブルーチン(というかクロージャ)へのポインタをリスト @error_list へ push するというコードを考えている。
前の foreach で変数のチェックとリストへの push、 後ろの foreach でクロージャを呼び出してエラーメッセージを表示する。
……はずなんだけど、上のコードでは上手くいかず、
CODE(0xba6004) が空です.
等と出力されてしまう。正しいコードは以下の通り。
# 上手くいくコード
($hensu1, $hensu2, $hensu3) = ('foo', '', 'bar');
@sr_list = ('hensu1', 'hensu2', 'hensu3');
foreach (@sr_list) {
my $sr_name = $_; # いったん待避させて使う
if (!$$sr_name) {
my $rs = sub { print "$sr_name が空です.\n" };
push(@error_list, $rs);
}
}
foreach (@error_list) {
&$_();
}
sub {}
の中で、$_ の指すモノが変わってしまったのが原因か。
ハッシュの全てのキーと値のペアを得る each()
の出力は、
突っ込んだ順などとは関係なくバラバラの順で出てくる。
ソートされた順にキーと値のペアを得て処理したい場合、 例えばハッシュ %h のキーを、対応する値でソートして得たいなら、
foreach (sort { $h{$b} <=> $h{$a} } keys %h) { ... }
とする。
マッチ演算子にオプション g をつけると (//g) どうなるかという話。 リストコンテキストで評価すると、マッチした部分全てをリストにして返す。
$str = '123 4567 abcd efg';
@list = $str =~ /\b\w{3}\b/g;
とすると、@list の内容は (123, efg) となる。
スカラーコンテキストで評価すると、普通に真偽値を返す。 つまり、マッチしていれば 1 を、さもなければ空文字列を返す。
$str = '123 4567 abcd efg';
$flag = $str =~ /\b(\S{3})\b/;
とすると、$flag には 1 が入る。
ここで ($flag) = ...
とすると、
$flag には '123' が入る(リストコンテキストだから)。
UNIX では特に意識する必要はない。 Windows では、入出力をバイナリモードで行う必要がある。 Windows でのデフォルトは ASCII モードで、このまま入出力を行うと、 勝手に改行コード変換が行われてしまい、データが正常に読み書きできない。
バイナリモードでの入出力を行うには、binmode() を使う。 引数はファイルハンドル。
open(OUTFH, "> hoge.dat");
binmode(OUTFH); # set filehandle to binary mode
print OUTFH pack("C*", 0x01, 0x02, 0x00);
$_ = "abracadabra";
$cnum = tr/a//; # count num of 'a'
正規表現の tr は、文字(文字列ではない。文字群?)の変換を行う。
tr/a-z/A-Z/
なんていうのをよくやるが、後のが空の場合、
変換は行われない。で、tr は変換「しようとした」文字の数を返すから、
これでカウントが可能。
tr はほかの正規表現と違って、^ とか $ とかの特殊文字が使えない (ハイフンによる範囲指定は使える)。変数展開もされないので、 変数に入ってる文字(列)の数を数えたい場合は次のようにする。
$str = 'abracadabra';
$c = 'a';
$cnum = $str =~ s/$c/$c/g; # $cnum = 5
$cnum = $str =~ /$c/g;
ではダメなことに注意。
$cnum = @tmplist = $str =~ /$c/g;
なら O.K.。
scalar() のリスト版ってないモンかなぁ……。
ヒアドキュメントの終端文字列は、ファイルとかパッケージとかの中で unique だったりする必要はない。次のようなコードでも全く問題はない。
print <<'END';
0
END
print <<'END';
1
END
print <<'END';
2
END
プロバイダの WWW サーバでどんなモジュールが使えるか調べたいときなどに。
% find `perl -e 'print "@INC"'` -name '*.pm' -print
shell が使えない場合は、perl で shell もどきを作って置けばいいでしょう。 受けた文字列を system() で実行するだけ? find が使えない場合も同様に。
どんどん増える。多分。