Perl/変数、データ構造
ここではPerlの変数とデータ構造についての基本的な事項を学びます。応用的な事項についてはリファレンスで触れます。
変数

Perlでは、変数は「データを格納する領域(オブジェクト)に付けられた名前」です。 同じオブジェクトを2つ以上の変数が指し示すこともありますし、配列の要素のように、単体では名前がないオブジェクトもあります。 変数を用いることにより、データをより柔軟に扱うことができます。
変数

変数の利用の形態は大きく分けて宣言、代入、参照の3種です。
変数

Perlには3つの組み込みデータ型があります。
変数

変数のデータ型は、接頭辞( sigil ; シジル)によって区別します。
データ型の種類

スカラーは、内部に構造をもたない「ただ一つ」の値を保持できるデータ型で、接頭辞は、$(ドルマーク;Scalar の S)です。
データ型の種類

Perlは、演算子式を評価するに当たり、演算子ごとにオペランドの型を強制的に変換します。
データ型の種類

次のプログラムは、等価な代入演算子による実装です。
データ型の種類

例外的に、インクリメント演算子は数値にも文字列にも作用します。
データ型の種類

このような文字列をオペランドに取ったときのインクリメントをマジカルインクリメントと呼びます。
データ型の種類

配列はスカラーの集合で、整数のインデックスでそれぞれの要素スカラーを参照できるデータ型で、接頭辞は、@(アットマーク;array の a)です。
データ型の種類

当たり前のようですが、動的型付けの言語の中では、意外と少数派です。
データ型の種類

このほか、Pythonも配列の代入は別名作成です。少数派ですが、PHPがPerlと同じです。
データ型の種類

配列にリテラルはありません。 配列リテラル風に見えるものはリストです。
データ型の種類

リストは、スカラー・配列やハッシュのようなデータ型ではなく書式です。
データ型の種類

配列変数の初期化にリストが使われるので紛らわしいのですが、
データ型の種類

リストは、複数の変数を一括宣言したり、多値代入につかわれます。
データ型の種類

配列とリストは似通っていますが区別する必要があります。
データ型の種類

なお、
データ型の種類

つぎに
データ型の種類

qw演算子を使って
データ型の種類

qw演算子は、空白で区切った文字のシーケンスを受け取り、区切られた文字列を要素とするリストを返します。
データ型の種類

10,4,2のように区切り文字をつけて出力したい場合、組込み関数 join を使うか、特殊変数$,を使います。
データ型の種類

sort関数を使うと、配列を並べ替える事ができます。 並べ替えることができますが、数値の配列であっても辞書順に並べ替えてしまいます。
データ型の種類

スライスは、配列やハッシュの部分集合へのアクセス方法を提供します。
データ型の種類

ハッシュは、キーとなる文字列とスカラーの値がペアの集合のデータ型です。ハッシュは配列とは違って、順序は一定でないことが保証されます。 ハッシュ変数の接頭辞は % です。
Perlが扱うデータ

Perlでは、演算子によってオペランドの型が決まるので、それに合わせて暗黙の型変換が起こります。 これは、明示的な型変換の手間を省く一方、プログラマーの意図とは異なる変換が行なわれる危うさも含んでいます。
Perlが扱うデータ

「Hello World」 のような文字列をPerl で扱う場合、"(ダブルクォーテーション)で囲みます。
Perlが扱うデータ

シングルクォーテーション ' ' で文字列を囲むことも出いますが、
Perlが扱うデータ

この2点がダブルクォーテーションで囲んだ場合と異なります。
Perlが扱うデータ

このように、Perlでは演算子がオペランドを暗黙に変換するので、演算子ごとのオペランド型の理解が大切になります。
Perlが扱うデータ

通常、引用符で囲まれた文字列は、リテラル値として考えられていますが、Perlでは演算子として機能し、様々な種類の補間やパターンマッチの機能を提供します。 Perlでは、これらの動作のために通常の引用符が用意されていますが、任意の引用符を選択する方法も用意されています。 次の表では、{}は区切り文字のペアを表しています。
Perlが扱うデータ

Perlの数値は、内部的にはネイティブな整数・ネイティブな浮動小数点数・数値を示す文字列で記憶します。 数値リテラルは、10進数、2進数(0bを前置), 8進数(0あるいは0oを前置), 16進数(0xを前置)によって数値を表現できます。 また、指数表現も可能です。
Perlが扱うデータ

Perlは、数値としての非数(NaN)と無限大(Inf)をサポートしています。 ただし、大概のNaNやInfが返りそうな演算では例外が上がって来ますし、数値リテラルとしての NaN や Inf はなく、"NaN" と "Inf" をつかいます。 このとき、大文字小文字を問わず単純な先頭一致なので、以下のような少し面倒な状況がおこります。
Perlが扱うデータ

変数 $n があるとき、 $n != $n が真なら NaN、abs($n) == "Inf" が真なら Inf または -Inf です。
Perlが扱うデータ

Perlに限らず、数値計算には誤差が伴います。 例えば、0.01 を 100 回足しても 1 にはなりません。 これを保証する方法はいくつかありますが、ここではカハンの加算アルゴリズムを紹介します。
特殊変数

プログラマーが変数を宣言しなくても、いくつかの変数は機能が決まっていて、事前にPerlに用意されており、このような変数を特殊変数あるいは処理系定義済み変数と言います。
特殊変数

たとえば特殊変数 $0 は、プログラム名が代入されています。
コンテキスト

変数、関数、定数などが、式の中でどのように評価されるか決定するものです。 大別するとスカラー・コンテキストとリスト・コンテキストがあり、スカラー・コンテキストにおかれた値はスカラーとして、リスト・コンテキストにおかれた値はリストとして評価されます。 コンテキストと実際のデータが食い違っている場合、次のような規則で評価されます。
コンテキスト

どのようにコンテキストが提供されるか、以下にいくつか例を示します。
コンテキスト

代入式は右辺に、左辺と同じコンテキストを提供します:
コンテキスト

配列はスカラー・コンテキストで評価されるとその要素数を返すので、結果として$numberには3が代入されます。 ただしこのような結果になるのは配列だけです。 前述したとおり、リストがスカラー・コンテキストで評価されると、最後の要素が返されます:
コンテキスト

これが $foo に代入されますが、残りの2つの変数については、対応する右辺値がない為未定義となります。 したがって、これは次のコードと等価です:
コンテキスト

フォワード宣言されたサブルーチンは、デフォルトで引数にリスト・コンテキストを提供します:
コンテキスト

これは次のように解釈されます。
コンテキスト

つまり、括弧のないサブルーチン呼び出しはリスト演算子として扱われます。
コンテキスト

もしこれを、
コンテキスト

と解釈させたいのなら、フォワード宣言にプロトタイプを付加することによって単項演算子として解釈させることができます:
コンテキスト

スカラー・コンテキストはさらに
コンテキスト

に細分され、評価されます。
コンテキスト

長さに制限のない文字列として扱われます。
コンテキスト

数値はそのまま文字列に変換され、未定義値は空文字列になります。リファレンスも文字列になりますが、文字列として処理されたリファレンスを再びリファレンスに戻すことはできません:
コンテキスト

数値リテラルとして解釈できる文字列は数値として扱われます。それ以外の文字があるとそこで解釈が終了します。
コンテキスト

ifやwhileなどの制御構文や修飾文、andやorなどの論理演算子が提供するコンテキストです。
コンテキスト

偽となるものは:
コンテキスト

であり、残りは全て真と解釈されます。
コンテキスト

「文字列'0'」とは'0'という文字列のことであり、数値コンテキストで0と解釈される文字列全てのことではないので注意してください。 次のものは全て真となります:
コンテキスト

評価した結果が捨てられてしまうので、値を期待しないコンテキストです。戻り値のない関数呼び出しなど、副作用を目的として使われます。 副作用もないコードは、perlに-wスイッチをつけて実行すると警告が発せられます:
型グロブ

Perlでは異なるデータ型に対して同じ識別子を与えることができます:
型グロブ

Perl処理系は内部に識別子テーブルと呼ばれるハッシュを持っています。そのキーは識別子であり、対応する値は型グロブというデータ構造です。型グロブは同じ識別子を持つすべてのデータ型へのリファレンスを格納しています。つまり上記の例だと識別子'foo'の型グロブにはスカラー、配列、ハッシュ、サブルーチンという4つのデータ型へのリファレンスが格納されています。型グロブは識別子の前に'*'というプレフィックスを付加して表現されます:
型グロブ

型グロブ自身はリファレンスを格納したハッシュであり、キーはデータ型の名前です:
型グロブ

型グロブもデータ構造の一つですから、代入や評価ができます。型グロブに別の型グロブを代入すると、変数の別名(エイリアス)を定義することが出来ます:
型グロブ

これはかつてPerlにリファレンスがなかった頃、サブルーチンに引数を参照渡しするのに利用されていました。また、ファイルハンドルとフォーマットにはプレフィックスが存在しないので、これらを受け渡しする場合の唯一の手段でもありました。
型グロブ

現在ではリファレンスが利用できるので、型グロブを使う必要はありません。ファイルハンドルやフォーマットに関してもIOモジュールなどでオブジェクトとして扱うことができます。
型グロブ

なお、型グロブは識別子テーブルの実体そのものですから、ブロックに結び付けられたレキシカルスコープにすることはできません。言い換えると、local変数にはできるがmy変数にはできません。
型グロブ

また、特定のデータ型のリファレンスを代入すると、そのデータ型に限定して別名を定義できます: