PERLDATA(1) USER COMMANDS PERLDATA(1) NAME perldata - Perl のデータ構造 DESCRIPTION 変数名 Perl には、スカラ、スカラの配列、「ハッシュ」とも呼ばれるス カラの連想配列という 3 つのデータ構造があります。 通常の配 列は 0 を基点とする数値でインデクスされます。 (負の添字は、 配列の終わりからインデクスします。) ハッシュ配列は、文字列 でインデクスされます。 スカラ値の参照は、配列の一要素であるスカラを参照する場合でも、 常に名前に '$' を付けます。 以下のようなものが使えます: $days # 単純なスカラ変数 "days" の値 $days[28] # 配列 @days の 29 番目の要素の値 $days{'Feb'} # ハッシュ %days の 'Feb' の値 $#days # 配列 @days の最後のインデクス値 ただし、配列全体や配列のスライスは '@' で示します: @days # ($days[0], $days[1],..., $days[n]) @days[3,4,5] # @days[3..5] と同じ @days{'a','c'} # ($days{'a'},$days{'c'}) と同じ ハッシュ全体は '%' で示します: %days # (key1, val1, key2, val2,...) さらに、サブルーティンは名前の前に '&' を付けて示しますが、 曖昧にならなければ、(英語でもほとんど使われなくなった "do" のように) 省略することができます。 シンボルテーブルのエント リは、名前に '*' を付けて示すことができますが、使用に際して は十分に注意する必要があります。 変数のすべての型には、それぞれの名前空間があります。 衝突を 心配せずに、スカラ変数、配列、ハッシュ (ついでにファイルハン ドルやサブルーティン名、ラベル) に、同じ名前を付けることがで きます。 つまり、$foo と @foo は 2 つの異なる変数であるとい うことです。 また、$foo[1] は @foo の一部であって、$foo の 一部ではありません。 奇妙に思えるかもしれませんが、それで良 いのです。奇妙なのですから。 変数と配列の参照は、いつも '$'、'@'、'%' で始まりますから、 「予約」語は、変数名としては、本当の意味で予約されているわけ ではありません。 (しかしながら、先頭に特別な文字を付けない、 ラベルやファイルハンドルとしては、予約されていることになりま す。 たとえば、"log" といった名前のファイルハンドルを使うこ とはできません。 ヒント: open(log,'logfile') などではなく、 open(LOG,'logfile') としてください。 大文字のファイルハンド ルを使えば、読みやすくもなりますし、将来に渡る予約語との衝突 Perl manpages Last change: Release 5.0 Patchlevel 00 1 PERLDATA(1) USER COMMANDS PERLDATA(1) も避けられます。) 大文字と小文字は区別されますから、"FOO"、 "Foo"、"foo" は、すべて違う名前です。 英字と下線で始まる名 前は、名前の一部に数字や下線を含むことができます。 そのような英数字の名前を、その型のオブジェクトへのリファレン スを返す式で置き換えることも可能です。 詳しくは、perlref manpage を参照してください。 数字で始まる名前には、数字しか含めることができません。 英字、 下線、数字以外の文字で始まる名前は、"$%" や "$$" のように 1 文字に限定されます。 (これら 1 文字の名前の多くは、Perl が あらかじめ意味を定めています。 たとえば、$$ はカレントプロ セスのプロセス id を示します。) (訳注: $^A など 2 文字が続く変数が Version 3 の終わり頃から、 いくつかできています。 ただし、^A の 2 文字を control-A の 1 文字 (16 進数の 0x01) で置き換えることも可能です。) コンテキスト Perl における演算や値の解釈は、その演算や値の置かれたコンテ キストからの要求に依存する場合があります。 このコンテキスト というものには大きく 2 つあり、スカラコンテキストとリストコ ンテキストと呼ばれます。 リストが要求されるコンテキストでは リスト値を返し、そうでなければスカラ値を返すような演算も存在 します。 (そのような演算については、ドキュメントでその演算 に触れるときに付記しています。) 言い方を変えると、Perl では、 ある種の演算が 1 つの値を返して欲しいか、複数の値を返して欲 しいかによって多重定義されているということです。 ("fish" や "sheep" といった、単複同形の英単語と似ているかもしれません。) 逆に、演算子は自分の引数が、スカラコンテキストとリストコンテ キストのどちらで解釈されるかを決めてしまいます。 たとえば、 int( <STDIN> ) と書くと、int 演算子は、自分の引数である <STDIN> 演算子がス カラコンテキストで評価されることを期待するため、<STDIN> は、 STDIN から 1 行を読み出し int 演算子に渡します。 int 演算子 は、その行から整数値を取り出して返すことになります。 これに 比べて、もし、 sort( <STDIN> ) と書いたなら、sort 演算子は、<STDIN> 演算子がリストコンテキ ストで評価されるようにするため、<STDIN> は STDIN から読める 限り最後の行まで読み出し、その行のリストを sort のルーティン に返します。 sort ルーティンは受け取った行のリストをソート して、ソートした結果のリストが値となります。 代入演算は少し特殊です。 代入では、右引数のコンテキストを決 めるために左引数が使われます。 スカラへの代入では、右側をス カラコンテキストで評価しますが、配列や配列のスライスに対する Perl manpages Last change: Release 5.0 Patchlevel 00 2 PERLDATA(1) USER COMMANDS PERLDATA(1) 代入では、右側をリストコンテキストで評価することになります。 リストへの代入も右側をリストコンテキストで評価することになり ます。 ユーザが定義するサブルーティンは、自分がスカラコンテキストで 呼ばれたか、リストコンテキストで呼ばれたかを意識することがで きますが、多くのサブルーティンでは意識する必要もないでしょう。 スカラ値は自動的にリストの要素になることができるからです。 perlfunc manpage の wantarray の項を参照してください。 スカラ値 スカラ変数には、数値、文字列、リファレンスのような、さまざま な種類の単独データを保持することができます。 一般に、1 つの 形式から他への変換は透過的です。 (スカラに複数の値を保持す ることはできませんが、複数の値を持っている配列やハッシュへの リファレンスを保持することができます。) スカラの値どうしは、 自動的に変換されるので、スカラを返す演算や関数では、コンテキ ストが文字列を要求しているのか、数値を要求しているのかを意識 する必要がないのです (実際は意識することができないのですが)。 スカラ値は、その値が空文字列か数値の 0 (あるいは同値な文字列 "0") 以外の場合には、ブール値の真として扱われます。 ブール 値が必要となるコンテキストは、単に特別なスカラコンテキストと して扱われます。 スカラのヌルには、実は defined と undefined の 2 種類があり ます。 undefined のヌルは、エラーがあったときや、ファイルの 終わりに達したとき、初期化していない変数や配列要素を参照した ときなど、何かに対する実際の値が存在しないときに返されます。 undefined のヌルは、最初に defined であるかのように使ったと きに defined となり得ますが、それに先立って値が defined かど うかを調べるために defined() 演算子を使うことができます。 配列の大きさはスカラ値です。 配列 @days の大きさは、csh の ように $#days を評価するとわかります。 (実際は、これは大き さではなく、最後の要素に対する添え字になります。 (通常は) 0 番目の要素があるからです。) $#days に代入を行なうと、配列 の大きさも変化します。 この方法で配列を小さくすると、見えな くなった部分の値は破壊されます。 小さくした配列を再び大きく しても、以前存在した要素に対する前の値が回復することはありま せん。 (Perl 4 では回復可能でしたが、デストラクタが期待どう りの時点で呼ばれることを保証するために、これを止めました。) 大きくなるであろう配列を、あらかじめ大きくしておくことで、あ る程度の効率を得ることもできます。 (最後の要素よりも後ろに 離れた位置に代入を行なうことでも、配列を大きくすることができ ます。) 配列に空リスト () を代入すると何も無い状態にまで、 切り詰めることができます。 以下の 2 つは等価です: @whatever = (); $#whatever = $[ - 1; Perl manpages Last change: Release 5.0 Patchlevel 00 3 PERLDATA(1) USER COMMANDS PERLDATA(1) 名前のある配列をスカラコンテキストで評価すると、配列の大きさ が返されます。 (これは、リストに対しては成り立ちません。 この場合には、C のコンマ演算子と同じく最後の値が返されます。) 以下は常に真となります: scalar(@whatever) == $#whatever - $[ + 1; Perl version 5 では $[ の意味を変更し、$[ を設定していないフ ァイルで、他のファイルがこの変数を変更しているかどうかを、気 にする必要がなくなりました。 (言い換えると、$[ は使わないほ うが良いと言うことです。) ですから、普通は以下のようになり ます。 scalar(@whatever) == $#whatever + 1; ハッシュをスカラコンテキストで評価した場合、ハッシュの中に 1 つでも key/value のペアが登録されているときにだけ、真となる 値が返されます。 (key/value のペアが登録されていれば、返さ れる値は、使用しているエントリの数と、割り付けられているエン トリの数を、スラッシュで区切った文字列です。 これは、与えた データに対して、Perl の (コンパイルされた) ハッシュのアルゴ リズムが、うまく動作しないかを確認するときくらいにしか使えま せんが。 たとえば、ハッシュに 10,000 のものを入れ、%HASH を スカラコンテキストで評価したときに "1/16" が得られれば、16 のうち 1 つのエントリだけが使われ、おそらくそこに 10,000 す べてが入っていることを意味します。 ほとんど起こりそうもない ことですが。) スカラ値の構成 数値リテラルは、慣習的な浮動小数点数と整数の形式で示されます: 12345 12345.67 .23E-10 0xffff # 16 進数 0377 # 8 進数 4_294_967_296 # 下線は読みやすさのため 文字列リテラルは、シングルクォートかダブルクォートで区切られ ます。 これらは、シェルのクォートと同じように扱われ、ダブル クォートの文字列リテラルでは、バックスラッシュの置換と変数の 置換が行なわれ、シングルクォートの文字列では、("\'" と "\\" を除いて) これらの置換は行なわれません。 普通の UNIX での バックスラッシュの置換規則は、改行やタブを始め、ある種の変わ った形式のためにも使われます。 一覧は perlop manpage の qq のところをご覧ください。 また、文字列に直接、改行を埋め込むこともできます。 つまり、 文字列は、開始した行で終了する必要はないと言うことです。 こ れは素晴らしいのですが、終了のクォートを付け忘れた場合には、 次にクォート文字が見つかるまでの間、Perl はエラーを見つける Perl manpages Last change: Release 5.0 Patchlevel 00 4 PERLDATA(1) USER COMMANDS PERLDATA(1) ことができなくなります。 それは、スクリプト上でずっと先にな るかもしれません。 文字列中での変数の置換は、スカラ変数と配 列と配列のスライスに限定されています。 (言い換えれば、$ や @ で始まる識別子か、それに大括弧で括った添え字をつけたもので す。) 次のプログラムは "The price is $100." と印字します。 $Price = '$100'; # 置換されない print "The price is $Price.\n"; # 置換される いくつかのシェルと同じように、識別子の前後に中括弧を入れて、 つながっている英数字から切り離すことができます。 また、シン グルクォート文字列は、その前の単語とスペースで区切らなければ ならないことに注意してください。 シングルクォートが (使わな いように言われていますが) 識別子を構成する文字として有効なも のだからです (perlmod manpage のパッケージのところを参照して ください)。 __LINE__ と __FILE__ という 2 つの特別なリテラルがあって、プ ログラムのその時点での行番号とファイル名を示します。 これら は、独立したトークンとしてだけ使用することができ、文字列の中 に展開することはできません。 さらに、トークン __END__ は、 スクリプトを納めたファイルの実際の最後よりも前で、論理的にス クリプトが終わるとき、その位置を示すのに使うことができます。 それ以降のテキストは無視されますが、DATA というファイルハン ドルを通して読むことができます。 (ファイルハンドル DATA は、 main のスクリプトからだけ読むことができ、require されたファ イルや eval された文字列からは読めません。) コントロール文 字 ^D と ^Z を __END__ の同義語として使うことができます。 文法的に別の解釈ができない単語は、クォート文字列であるかのよ うに扱われます。 これは「裸の単語」と言われます。 ファイル ハンドルやラベルと同様に、小文字だけからなる裸の単語は、将来 的に予約後とぶつかる危険がありますから、そのような単語があっ た場合、-w スイッチをつけることで、Perl がその単語を指摘して くれます。 裸の単語をなくして欲しいという方もいらっしゃいま す。 もし、 use strict 'subs'; と書いておけば、サブルーティンコールと解釈できない裸の単語が コンパイル時にエラーとなります。 この制約は囲っているブロッ クの終わりまで有効です。 内側のブロックで no strict 'subs' と書くことで、この機能を撤回することもできます。 配列変数は、ダブルクォート文字列中で、配列のすべての要素を変 数 $" 中に示す区切文字 (デフォルトはスペース) でつなげて展開 されます。 以下は同値です: $temp = join($",@ARGV); system "echo $temp"; system "echo @ARGV"; Perl manpages Last change: Release 5.0 Patchlevel 00 5 PERLDATA(1) USER COMMANDS PERLDATA(1) 検索パターン (ここでも、ダブルクォートのような置換が行なわれ ます) の中では、解釈する上で曖昧となる場合ができてきます。 /$foo[bar]/ は、/${foo}[bar]/ と解釈される (この場合 [bar] は、正規表現の文字クラス) のでしょうか、/${foo[bar]}/ と解釈 される (この場合 [bar] は、配列 @foo の添え字) のでしょうか。 @foo が他に存在しない場合には、明らかに文字クラスとなります。 @foo が存在すれば、Perl が [bar] の意味に見当をつけますが、 たいてい正しい解釈をします。 もし、見当があたっていないとき や、偏執的にこだわりたい時には、上に書いたように中括弧を付け て、強制的に解釈のしかたを決めることができます。 行指向形式のクォートは、シェルの「ヒアドキュメント」構文をも とにしています。 << の後にクォートされるものを終了する文字 列を示し、現在行の次の行からその終了文字列に一致する行の前の 行までが、その項目の値となります。 終了文字列には、識別子 (単語) かクォートされたテキストが許されます。 クォートされ ている場合には、そのクォート文字の種類によって、実際にクォー トされるテキストの扱いが、通常のクォートと同様にして決められ ます。 クォートされていない識別子とした場合には、ダブルクォ ートのように扱われます。 << と識別子の間にスペースを入れて はいけません。 (もしスペースを入れると、空識別子として扱わ れ、最初の空行にマッチするようになります。 下記の Merry Christmas の例を参照してください。) 終了文字列は、その終了 を示す行に単独で (クォートもしないで、前後に空白を入れること も無く) 置かなければなりません。 print <<EOF; # 上記と同じ The price is $Price. EOF print <<"EOF"; # これも同じ The price is $Price. EOF print << x 10; # 正しいが、使わないように。<<"" を使う。 Merry Christmas! print <<`EOC`; # 実際にクォートされたコマンドを実行 echo hi there echo lo there EOC print <<"foo", <<"bar"; # スタックすることも可能 I said foo. foo I said bar. bar Perl manpages Last change: Release 5.0 Patchlevel 00 6 PERLDATA(1) USER COMMANDS PERLDATA(1) myfunc(<<"THIS", 23, <<'THAT''); Here's a line or two. THIS and here another. THAT 文を終了するためのセミコロンを付けなければいけないことは、忘 れないでください。 以下のようにしたいのではないと言うことを Perl が知ることはできないのですから: print <<ABC 179231 ABC + 20; リスト値の構成 リスト値は、個々の値をコンマで区切って (必要に応じて括弧で括 って) 示されます: (LIST) リスト値が要求されていないコンテキストでは、リストリテラルの 値としては、C のコンマ演算子の場合のように、最後の要素の値が 使われます。 たとえば、 @foo = ('cc', '-E', $bar); は、リスト値全体を配列 foo に代入しますが、 $foo = ('cc', '-E', $bar); は、変数 bar の値を変数 foo に代入します。 本物の配列がスカ ラコンテキストで評価されたときの値は、その配列の大きさとなり ます。 以下の例では、$foo に 3 という値が代入されます: @foo = ('cc', '-E', $bar); $foo = @foo; # $foo は 3 となる リストリテラルの閉じ括弧の前には余分にコンマを置いてかまいま せんので、 @foo = ( 1, 2, 3, ); と書くことができます。 Perl manpages Last change: Release 5.0 Patchlevel 00 7 PERLDATA(1) USER COMMANDS PERLDATA(1) リストの中にリストがある場合には、自動的に展開されてしまいま す。 これは、外側のリストが評価されると、リストの個々の要素 がリストコンテキストで評価され、その結果のリスト値の個々の値 が、元のリストの要素であるかのように展開されるのです。 つま り、リストの中では配列も、その性質が現れてきません。 (@foo,@bar,&SomeSub) というリストは、@foo のすべての要素の後に @bar のすべての要 素を続け、その後に SomeSub というサブルーティンが返すすべて の要素を続けたものを要素として持ちます。 展開されないリスト のリファレンスを作るためには、perlref manpage を参照してくだ さい。 空リストは () で表わされます。 リスト中で空リストを展開して も何も起こりません。 つまり、 ((),(),()) は () と等価です。 同様に、要素のない配列を展開することは、その場所に何も展開し なかったのと同じことになります。 リスト値にも通常の配列と同じように、添え字をつけることができ ます。 リストには、曖昧さをなくすために、括弧を付けなくては なりません。 例: # stat はリスト値を返す $time = (stat($file))[8]; # 16 進の数字を探す $hexdigit = ('a','b','c','d','e','f')[$digit-10]; # 「逆コンマ演算子」 return (pop(@foo),pop(@foo))[0]; リストを構成する個々の要素すべてに代入が許される場合には、全 体のリストに代入を行なうことができます: ($a, $b, $c) = (1, 2, 3); ($map{'red'}, $map{'blue'}, $map{'green'}) = (0x00f, 0x0f0, 0xf00); リストの最後の要素は、配列やハッシュでもかまいません: ($a, $b, @rest) = split; local($a, $b, %rest) = @_; 実際は、リストの任意の要素として配列を使うことができますが、 リスト中の最初の配列が、右辺の値をすべて取り込んでしまうため、 それ以降のものはヌルしか受け取ることができません。 これは、 local() や my() では有用かもしれません。 ハッシュリテラルは key と value と解釈される値のペアで構成さ れます: Perl manpages Last change: Release 5.0 Patchlevel 00 8 PERLDATA(1) USER COMMANDS PERLDATA(1) # 上記の map の代入と同じ %map = ('red',0x00f,'blue',0x0f0,'green',0xf00); key と value のペアの間には => 演算子を使うと読みやすくなり ます (実際のところ => 演算子は、見た目に目立つコンマの同義語 でしかありません): %map = ( 'red' => 0x00f, 'blue' => 0x0f0, 'green' => 0xf00, ); スカラコンテキストにおける配列代入は、代入の右辺の式で作られ る要素の数を返します: $x = (($foo,$bar) = (3,2,1)); # $x は 2 ではなく 3 これは、ブールコンテキストでリストの代入を行ないたい時に、と ても便利です。 多くのリスト関数は最終的に空リストを返し、そ れが代入されると 0 となり、偽として解釈されるからです。 Perl manpages Last change: Release 5.0 Patchlevel 00 9