PERLTRAP(1) USER COMMANDS PERLTRAP(1)
NAME
perltrap - Perl の不注意によるわな
DESCRIPTION
もっとも大きなわなは、-w スイッチを忘れることです。 perlrun
manpage を参照してください。 プログラムで
use strict;
と指定した上で、実行できるようにしておけば、突然の事故を未然
に防いでくれますが、その場限りのプログラムにはめんどうすぎる
要求でしょう。
Awk のわな
Awk になれた方は、以下のようなことに、特に注意してください:
+ English モジュールを
use English;
としてロードすれば、awk でのようにして特殊変数を ($RS の
ように) 参照することができます。 詳しくは、perlvar
manpage を参照してください。
+ Perl では、(ブロックの最後を除いて) すべての単純実行文に
セミコロンが必要です。 改行が実行文の区切り文字とはみな
されません。
+ if や while には、中括弧が必須です。
+ Perl では、変数は "$" や "@" で始まります。
+ 配列のインデクスは 0 からです。 substr() や index() で
の文字列中の位置も同様です。
+ 配列のインデクスを、数値にするか文字列にするかを決めなく
てはなりません。
+ 連想配列の値は、単に参照するだけでは存在することになりま
せん。
+ 文字列比較を行なうのか、数値比較を行なうのかを決めなけれ
ばなりません。
+ 入力を読み込むだけでは、split は行なわれません。 自分で
split を行なって、明示的に配列に入れる必要があります。
また、split() 演算子は、引数が違います。
+ 現在行は通常、$0 ではなく、$_ に入れられています。 一般
に、行末の改行文字は削除されていません。 ($0 は、実行さ
Perl manpages Last change: Release 5.0 Patchlevel 00 1
PERLTRAP(1) USER COMMANDS PERLTRAP(1)
れているプログラムの名前です。) perlvar manpage を参照
してください。
+ $<数字> は、フィールドを参照するものではありません。 こ
れは、最後のパターンマッチで、マッチした部分文字列を参照
するものです。
+ $, や $\ を設定しない限り、print() 文はフィールドセパレ
ータやレコードセパレータを付与しません。 English モジュ
ールを使えば、$OFS や $ORS を設定することができます。
+ ファイルへ print するときには、前もって open しなければ
なりなせん。
+ 範囲演算子はコンマではなく ".." です。 コンマ演算子は、
C と同じように動作します。
+ マッチの拘束演算しは、"~" ではなく、"=~" です。 ("~" は
C と同じように 1 の補数をとる演算子です。)
+ 指数演算子は、"^" ではなく、"**" です。 "^" は C と同じ
く XOR 演算子です。 (awk が基本的に C と互換性がないこ
とにお気付きかもしれませんね。)
+ 連結演算子は、空文字列ではなく、"." です。 (空文字列を
使うと、/par/ /pat/ が解析できなくなります。 3 番目のス
ラッシュが除算演算子と解釈されるからです。 Perl の字句
解析部は、"/", "?", ">" のような演算子に対し、多少文脈依
存となっています。 実際、"." 自身も、数値の開始になるこ
ともあります。
+ キーワード next、exit、continue の働きが異なります。
+ 以下の変数の働きが異なります:
Awk Perl
ARGC $#ARGV or scalar @ARGV
ARGV[0] $0
FILENAME $ARGV
FNR $. - something
FS (whatever you like)
NF $#Fld, or some such
NR $.
OFMT $#
OFS $,
ORS $\
RLENGTH length($&)
RS $/
RSTART length($`)
SUBSEP $;
Perl manpages Last change: Release 5.0 Patchlevel 00 2
PERLTRAP(1) USER COMMANDS PERLTRAP(1)
+ $RS にパターンを設定することはできず、文字列だけです。
+ 疑わしいときには、awk の構文を a2p に通して、出力された
ものを見てみましょう。
C のわな
知的な C プログラマは、以下のことに注意すべきです:
+ if や while には、中括弧が必要です。
+ "else if" ではなく、"elsif" を使わなくてはなりません。
+ C のキーワード break と continue に相当するものは、Perl
では、それぞれ last と next になっています。 C とは違っ
て、これらは do { } while 構造では使えません。
+ switch 文はありません。 (しかし、大急ぎで作ることも簡単
です。)
+ Perl では、変数は "$" や "@" で始めます。
+ printf() では、フィールド長を展開する "*" フォーマットは
インプリメントされていませんが、ダブルクォート文字列のフ
ォーマット内で変数を展開すれば、同じことができます。
+ コメントは "/*" ではなく、"#" で開始します。
+ 任意のもののアドレスを得ることはできません。 Perl 5 に
おける同様の演算子はバックスラッシュですが、これはリファ
レンスを生成するものです。
+ ARGV は大文字で書かなければなりません。
+ link(), unlink(), rename() といったシステムコールは、成
功時に (0 ではなく)、0 以外を返します。
+ シグナルハンドラは、数字ではなくシグナル名を扱います。
使用できるシグナル名は、kill -l として確かめてください。
Sed のわな
熟練した sed プログラマは、以下のことに注意すべきです:
+ 置換文字列中の後方参照では "\" ではなく、"$" を使います。
+ パターンマッチのメタ文字 "(", ")", "|" は、前にバックス
ラッシュを置いてエスケープする必要はありません。
+ 範囲演算子は、コンマではなく "..." です。
Perl manpages Last change: Release 5.0 Patchlevel 00 3
PERLTRAP(1) USER COMMANDS PERLTRAP(1)
Shell のわな
鋭いシェルのプログラマは、以下のことに注意すべきです:
+ バッククォート演算子は、コマンド内にシングルクォートがあ
っても変数の展開を行ないます。
+ バッククォート演算子は、csh とは異なり、返された値を変換
しません。
+ シェル (特に csh) は、コマンドラインごとに、何段階もの置
換を行ないます。 Perl はダブルクォート、バッククォート、
山括弧、検索パターンといった特定の構造でだけ置換を行ない
ます。
+ シェルは、一時に少しづつ解釈を行ないます。 Perl は、実
行前にプログラム全体をコンパイルします (コンパイル時に実
行される BEGIN ブロックを除く)。
+ 引数は、$1, $2 などではなく、@ARGV から得られます。
+ 環境変数は、自動的には独立したスカラ変数として利用できる
ようになりません。
(訳注: Env モジュールが使用できます。)
Perl のわな
実践的な Perl プログラマは、以下のことに注意すべきです:
+ 多くの演算子が、スカラコンテキストとリストコンテキストと
では、動作が異なることを忘れないでください。 詳しくは、
perldata manpage を参照してください。
+ 裸の単語、特に全てが小文字のものは、できる限り使わないで
ください。 見た目だけでは、その「裸の単語」が関数なのか、
文字列なのかが判断できません。 文字列にはクォートを、関
数呼び出しには括弧を付ければ、迷うこともないでしょう。
+ どの組み込み関数が (chop() や chdir() のような) 単項演算
子で、どれが (print() や unlink() のような) リスト演算子
かは、単に眺めるだけではわかりません。 (ユーザ定義のサ
ブルーティンは、リスト演算子にすることができますが、単項
演算子にはなりません。) perlop manpage を参照してくださ
い。
+ いくつかの関数が $_ や @ARGV などをデフォルトにしていま
すが、同じことを期待する他の関数がデフォルトになっていな
いことを覚えるのに、辛いタイピングが必要でしょう。
(have a hard time の "time" と "type" をかけているのは、
どう訳そう(^^;)
Perl manpages Last change: Release 5.0 Patchlevel 00 4
PERLTRAP(1) USER COMMANDS PERLTRAP(1)
+ "=~" が必要なところで "=" を使わない事を忘れないようにし
てください。 この 2 つの構文はかなり違います:
$x = /foo/;
$x =~ /foo/;
+ do {} 構造は本物のループではないので、ループ制御を行なえ
ません。 (訳注: 原文はそう言っていない気もするが。)
+ ローカル変数は、my() で済むところでは、これで済ませるこ
と (使えない場所については、perlform manpage を参照して
ください)。 local() を使えば、グローバル変数に対するロ
ーカルな値を与えますが、動的スコープの不慮の副作用の可能
性は、そのままです。
Perl4 のわな
悔い改めた Perl 4 のプログラマは、以下に示すリリース 4 とリ
リース 5 の間の互換性のない修正点に注意すべきです:
+ ダブルクォートタイプの文字列で、@ は必ず配列を展開します。
@ を展開しないようにするように、バックスラッシュを使わな
ければならないプログラムもあるでしょう。
+ Perl にとって文字列のように見えていた裸の単語は、それ以
前に、その名前のサブルーティンが定義されていれば、サブル
ーティンコールと解釈されるようになりました。 たとえば:
sub SeeYa { die "Hasta la vista, baby!" }
$SIG{QUIT} = SeeYa;
Perl 4 では、シグナルハンドラを設定しますが、Perl 5 では、
実際に関数を呼び出し、その結果を設定します ! -w スイッ
チを使えば、このようなものを探してくれます。
+ "_" で始まるシンボルは、$_ 自身 (と @_ など) を除いて、
package main に存在しなくてもよくなりました。
+ s'$lhs'$rhs' では、どちら側でも展開を行なわなくなりまし
た。 以前は、$rhs は展開しませんでしたが、$lhs は展開し
ました。
+ splice() の 2 番目の引数と 3 番目の引数が (本に書いてあ
ったように) リストコンテキストではなく、スカラコンテキス
トで評価されるようになりました。
Perl manpages Last change: Release 5.0 Patchlevel 00 5
PERLTRAP(1) USER COMMANDS PERLTRAP(1)
+ 優先順位によって意味エラーが起こります:
shift @list + 20;
$n = keys %map + 20;
これらがうまく行けば、以下がうまく行きません:
sleep $dormancy + 20;
+ open FOO || die は、もはや正しくありません。 ファイルハ
ンドルの前後に括弧が必要です。 一時的にサポートされてい
ましたので、このような構文を使うと致命的ではない (がサプ
レスできない) 警告が出ます。
(訳注: "or" 演算子を使用することができます。)
+ フォーマット文の引数リストの要素は、リストコンテキストで
評価されるようになりました。 このことにより、リスト値を
展開できるようになりました。
+ 最適化によってなくなるブロック内に goto することはできま
せん。 ちぇっ。
+ 空白を変数名やクォート構文の区切り文字に使うことは、もは
や構文的に正しくなくなりました。 ちぇっ、ちぇっ。
+ 関数 caller() は呼び元がないとき、スカラコンテキストで偽
を返すようになりました。 これにより、ライブラリファイル
は、自分が require されたものかを判断できます。
+ m//g は状態を正規表現の方にではなく、検索文字列の方に括
りつけます。
+ sort のサブルーティン名として、reverse というものは、許
されなくなりました。
+ taintperl は、もはや独立した実行ファイルとして存在しませ
ん。 自動的に汚染チェックが on にならないときのために、
-T スイッチが用意されています。
+ ダブルクォート文字列が、エスケープされていない $ や @ で
終了することがなくなりました。
+ 古い while/if BLOCK BLOCK の構文は、もはやサポートされて
いません。
+ 配列に負の添え字を与えると、配列の終わりから数えるように
なりました。
+ コンマ演算子をスカラコンテキストで使うと、引数にもスカラ
コンテキストが適用されることを保証するようになりました。
Perl manpages Last change: Release 5.0 Patchlevel 00 6
PERLTRAP(1) USER COMMANDS PERLTRAP(1)
+ ** 演算子は、単項のマイナスよりも強く結合するようになり
ました。 このように動作するように、ドキュメントに書かれ
ていましたが、そうなっていませんでした。
+ $#array を小さく設定すると、それ以降の配列の要素を捨てま
す。
+ delete() は tie された配列の古い値を返すことが保証されま
せん。 この機能は、いくつかのモジュールにとってインプリ
メントがめんどうだからです。
+ 異なるエラーメッセージがあります。
+ いくつかのバグが、迂闊にも修正されているかもしれません。
訳注: 原文には、Accustomed awk users、Cerebral C Programmers、
Seasoned sed programmers、Sharp shell programmers、Practicing
Perl Programmers、Penitent perl 4 Programmers といった言葉の
遊びがみられますが、力及ばず訳出できませんでした。
Perl manpages Last change: Release 5.0 Patchlevel 00 7