PERLSYN(1)               USER COMMANDS                 PERLSYN(1)



NAME
     perlsyn - Perl の構文

DESCRIPTION
     Perl のスクリプトは宣言と実行文の列で構成されます。 Perl で
     宣言の必要があるのは、レポートフォーマットとサブルーティンだ
     けです。 これらの宣言については、後ほど詳しく述べます。 ユ
     ーザが造った初期化していないすべてのオブジェクトは、代入など
     の明示的な操作で定義されない限り、ヌルもしくは 0 の値を持っ
     ているとものとして扱われます。 (しかし、未定義の値を使った
     場合に警告を出すようにすることもできます。) sed や awk のス
     クリプトでは、実行文の列は入力行ごとに繰り返して実行されます
     が、Perl では、実行文の列は 1 度実行されるだけです。 これは、
     入力ファイルに対して明示的に自分でループを行なわなければなら
     ないことを意味していますが、どのファイルのどの行に注目するか
     を自由に制御できることも意味しています。 (本当は、私はウソ
     を付いています。 -n か -p スイッチを使えば、暗黙にループを
     行なうことができます。 sed や awk のように必須のデフォルト
     になっていないだけのことです。)

     Perl は、ほとんどすべての部分で、自由形式の言語です。 (理由
     は自明であると思われますが、フォーマット宣言が唯一の例外とな
     っています。) コメントは、文字 "#" によって示され、行末まで
     となります。 C のスタイルの /* */ を使おうとした場合には、
     文脈によって、割り算かパターンマッチかのいずれかに解釈され、
     C++ の // コメントは、空の正規表現に見えます。 使わないよう
     にしましょう。

     宣言は実行文が置けるところであれば、どこにでも置けますが、実
     行文の列を実行するのに影響を与えません。 宣言はコンパイル時
     にのみ意味を持ちます。 普通は、すべての宣言をスクリプトの最
     初か、最後にまとめておきます。

     Perl 5 から、サブルーティンを宣言することで、宣言した場所以
     降では、サブルーティン名をリスト演算子のようにして使うことが
     できるようになりました。 サブルーティンは以下のように、定義
     しないで宣言することができます:

         sub myname;
         $me = myname $0             or die "can't get myname";

     リスト演算子として働きはしますが、単項演算子ではありませんの
     で、|| ではなく or を使うことに注意してください。

     サブルーティンの宣言は、use 文を使ってインポートすることもで
     きます。

     Perl 5 からはまた、実行文の列に字句スコープの変数宣言を、含
     めることができるようになりましたが、変数名を宣言することを除
     けば、宣言文は通常の実行文と同様に働き、通常の実行文であるか
     のように他の文の中に埋め込まれるのです。




Perl manpages Last change: Release 5.0 Patchlevel 00            1






PERLSYN(1)               USER COMMANDS                 PERLSYN(1)



     単純実行文

     唯一の単純実行文は、副作用を目的として評価される式です。 個
     個の単純実行文は、それがブロックの最後の文でなければ、お尻に
     セミコロンを付けなくてはなりません。 ブロックの最後の文では、
     セミコロンが省略可能です。 (ブロックが複数の行から成るので
     あれば、やはりセミコロンは付けた方が良いでしょう。 あとで、
     行を増やすこともあるでしょうから。) eval {} や do {} のよう
     に複合文に見える演算子もありますが、これは複合文ではありませ
     ん (式の中の「項」でしかありません) し、実行文の最後の項とな
     った場合には、明示的にセミコロンが必要です。

     どんな単純実行文にも、最後のセミコロン (もしくは、ブロックの
     終わり) の直前に 1 つだけ修飾子を付けることができます。 修
     飾子としては:

         if EXPR
         unless EXPR
         while EXPR
         until EXPR

     が使えます。

     if 修飾子と unless 修飾子は、英語ができる方なら、期待通りの
     意味となります。 while 修飾子と until 修飾子も通常の "while
     loop" の意味 (条件が先に評価される) となりますが、do-BLOCK
     (と現在は使わないようにしている do-SUBROUTINE 文) に対して使
     用すると、条件が評価される前に 1 度だけブロックが実行されま
     す。 これは:

         do {
             $_ = <STDIN>;
             ...
         } until $_ eq ".\n";

     のようなループが書けるようにするためです。 perlfunc manpage
     を参照してください。 後述するループ制御文は、この構文では使
     用できないことにも注意してください。 修飾子にはループラベル
     を付けることができないからです。 ごめんなさい。 そういった
     ことがしたい場合には、別のブロックを被せてしまうとよいでしょ
     う。)














Perl manpages Last change: Release 5.0 Patchlevel 00            2






PERLSYN(1)               USER COMMANDS                 PERLSYN(1)



     複合実行文

     Perl では、スコープが定義される実行文の列をブロックと呼んで
     います。 ときにはブロックは、そのブロックを含むファイルの単
     位で区切られ (この場合 require で読み込まれるか、プログラム
     全体ということになります)、また文字列として区切られる場合も
     あります (eval される場合です)。

     しかし、一般にはブロックは中括弧 (`{}') で区切られるのが普通
     です。 この構文上の構造を BLOCK と呼ぶことにします。

     以下の複合実行文を、流れの制御のために使うことができます:

         if (EXPR) BLOCK
         if (EXPR) BLOCK else BLOCK
         if (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK
         LABEL while (EXPR) BLOCK
         LABEL while (EXPR) BLOCK continue BLOCK
         LABEL for (EXPR; EXPR; EXPR) BLOCK
         LABEL foreach VAR (ARRAY) BLOCK
         LABEL BLOCK continue BLOCK

     C や Pascal と違って、文ではなく、BLOCK を使って定義されてい
     ることに注意してください。 これは中括弧が必須ということで、
     中ぶらりんの実行文が許されないということです。 中括弧を使わ
     ないで条件を書きたい場合には、方法がいくつかあります:

         if (!open(FOO)) { die "Can't open $FOO: $!"; }
         die "Can't open $FOO: $!" unless open(FOO);
         open(FOO) or die "Can't open $FOO: $!";     # FOO or bust!
         open(FOO) ? 'hi mom' : die "Can't open $FOO: $!";
                             # a bit exotic, that last one

     はすべて同じことをします。

     if 文は見た通りです。 BLOCK は必ず中括弧で括られますから、
     if と else の対応が曖昧になることはありません。 if の代わり
     に unless を使えば、テストの意味が逆になります。

     while 文は、式が真である間 (評価結果が、空文字列、0、"0" の
     いずれかでない間) ブロックを実行します。 LABEL はあっても無
     くてもよく、もし存在する時には、識別子にコロンを続けたもので
     す。 LABEL は、nextlastredo というループ制御文が、ルー
     プを識別できるようにするものです (以下を参照)。 continue
     BLOCK があれば、C の for ループの 3 番目の部分のように、次に
     条件が評価される直前に実行されます。 ですから、(C の
     continue 文と同様に) たとえ next 文でループを進めるときにも、
     ループ変数のインクリメントが行なうことができます。

     while を until で置き換えると、テストの意味が逆になりますが、
     繰り返しの前に、条件が評価されることは変わりません。




Perl manpages Last change: Release 5.0 Patchlevel 00            3






PERLSYN(1)               USER COMMANDS                 PERLSYN(1)



     if 文または while 文において、"(EXPR)" を BLOCK で置き換える
     ことができ、ブロックの最後に実行した文が真であれば、条件も真
     となります。 (この機能は Perl 5 でも機能しますが、使わない
     ようにしてください。 "if BLOCK" の代わりに "if (do BLOCK)"
     とすればよいでしょう。)

     C スタイルの for ループは、完全に対応する while ループと同じ
     ように動作します:

         for ($i = 1; $i < 10; $i++) {
             ...
         }

     は、

         $i = 1;
         while ($i < 10) {
             ...
         } continue {
             $i++;
         }

     と同じことです。

     foreach ループは通常のリスト値で繰り返しを行ない、変数 VAR
     にそのリストの値を順番に設定します。 その変数は、(前もって
     my で宣言したのでなければ) 暗黙のうちにループ内にローカルと
     なり、ループを抜けると以前の値に戻ります。 キーワードの
     foreach は、実際にはキーワード for の同義語であり、読みやす
     さのために foreach を、簡潔さのために for を使い分けることが
     可能です。 VAR を省略すると、$_ に個々の値が順に設定されま
     す。 もし、ARRAY が (リスト値を返す式ではなく) 本物の配列の
     時には、ループの中で VAR を修正することによって、その時に対
     応している配列の要素自身を修正することができます。 例:

         for (@ary) { s/foo/bar/; }

         foreach $elem (@elements) {
             $elem *= 2;
         }

         for ((10,9,8,7,6,5,4,3,2,1,'BOOM')) {
             print $_, "\n"; sleep(1);
         }

         for (1..15) { print "Merry Christmas\n"; }

         foreach $item (split(/:[\\\n:]*/, $ENV{'TERMCAP'})) {
             print "Item: $item\n";
         }





Perl manpages Last change: Release 5.0 Patchlevel 00            4






PERLSYN(1)               USER COMMANDS                 PERLSYN(1)



     BLOCK 自身は (ラベルが付いていても、いなくても) 意味的には、
     1 度だけ実行されるループと同じです。 つまり、ブロックを抜け
     たり、再度実行したりするのに、ループ制御文が使えるということ
     です。 continue BLOCK はあっても無くてもかまいません。 こ
     の構成は、case 構文を組み立てるのに便利です。

         SWITCH: {
             if (/^abc/) { $abc = 1; last SWITCH; }
             if (/^def/) { $def = 1; last SWITCH; }
             if (/^xyz/) { $xyz = 1; last SWITCH; }
             $nothing = 1;
         }

     Perl には、公に switch 文は存在しません。 同値なものが既に
     いくつもあるからです。 上にあげたものの他に、

         SWITCH: {
             $abc = 1, last SWITCH  if /^abc/;
             $def = 1, last SWITCH  if /^def/;
             $xyz = 1, last SWITCH  if /^xyz/;
             $nothing = 1;
         }

     とも書けます。 (これは、ループ制御「演算子」を式の中で使え
     ることに気が付けば、見た目ほど奇妙なものではありません。 普
     通の C のコンマ演算子です。)

     また、

         SWITCH: {
             /^abc/ && do { $abc = 1; last SWITCH; };
             /^def/ && do { $def = 1; last SWITCH; };
             /^xyz/ && do { $xyz = 1; last SWITCH; };
             $nothing = 1;
         }

     とも書けますし、もう少し「正当な」switch 文のように整形する
     と:

















Perl manpages Last change: Release 5.0 Patchlevel 00            5






PERLSYN(1)               USER COMMANDS                 PERLSYN(1)



         SWITCH: {
             /^abc/      && do {
                                 $abc = 1;
                                 last SWITCH;
                            };

             /^def/      && do {
                                 $def = 1;
                                 last SWITCH;
                            };

             /^xyz/      && do {
                                 $xyz = 1;
                                 last SWITCH;
                             };
             $nothing = 1;
         }

     となりますし、

         SWITCH: {
             /^abc/ and $abc = 1, last SWITCH;
             /^def/ and $def = 1, last SWITCH;
             /^xyz/ and $xyz = 1, last SWITCH;
             $nothing = 1;
         }

     や、醜くも

         if (/^abc/)
             { $abc = 1 }
         elsif (/^def/)
             { $def = 1 }
         elsif (/^xyz/)
             { $xyz = 1 }
         else
             { $nothing = 1 }

     としてもよいでしょう。
















Perl manpages Last change: Release 5.0 Patchlevel 00            6