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