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 の字句
         解析部は、"/", "?", ">" のような演算子に対し、多少文脈依
         存となっています。 実際、"." 自身も、数値の開始になるこ
         ともあります。

     +   キーワード nextexit、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
         では、それぞれ lastnext になっています。 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