Go to the first, previous, next, last section, table of contents.


ハードリファレンスの参照

  1. 変数名やサブルーティン名の一部として識別子を置くところでは、適切な型のリ ファレンスを持った単純スカラ変数で、その識別子を置き換えることができます:
    $bar = $$scalarref;
    push(@$arrayref, $filename);
    $$arrayref[0] = "January";
    $$hashref{"KEY"} = "VALUE";
    &$coderef(1,2,3);
    
    $arrayref[0]$hashref{"KEY"} という形で被参照しているの ではないことが大切です。スカラ変数の被参照は、いかなる key の検索よりも 「前に」行なわれます。単純スカラ変数より込み入ったものはすべて、以下の 2 番か 3 番の方法が採られます。しかしながら、「単純スカラ」には、この 1番 目の方法を再帰的に使っている識別子も含まれます。したがって、
    $refrefref = \\\"howdy";
    print $$$$refrefref;
    
    は、"howdy" と出力します。
  2. 変数名やサブルーティン名の一部として識別子を置くところでは、適切な型のリ ファレンスを返す BLOCK を伴う識別子で置き換えることができます。言い換え ると、先の例は以下のように書くことができます:
    $bar = ${$scalarref};
    push({$arrayref}, $filename);
    ${$arrayref}[0] = "January";
    ${$hashref}{"KEY"} = "VALUE";
    &{$coderef}(1,2,3);
    
    確かに、この場合には中括弧を付けるのは、莫迦げたことかもしれませんが、 BLOCK には任意の式、特に添字を付けた式を入れることができます:
    &{ $dispatch{$index} }(1,2,3);      # 正しいルーティ
                                        # ンの呼び出し
    
    単純な $$x の場合に中括弧が省略できるので、シンボルの被参照を適当 な演算子のように受け取って、その優先順位はどのくらいかと悩む人があります。 しかし、もし演算子であれば、中括弧の代わりに、普通の括弧が使えることでしょ う。そうではありません。以下の違いを考えてみてください。CASE 0 は、CASE 1 を短くしたものであり、CASE 2 ではありません:
    $$hashref{"KEY"}   = "VALUE";       # CASE 0
    ${$hashref}{"KEY"} = "VALUE";       # CASE 1
    ${$hashref{"KEY"}} = "VALUE";       # CASE 2
    ${$hashref->{"KEY"}} = "VALUE";     # CASE 3
    
    CASE 2 もまた、間違えやすいもので、%hashref という変数をアクセス するものです。$hashref を仲介して、それが指すことになっているハッ シュを被参照しているいるものでは、ありません。それは、CASE 3 です。
  3. 配列の個々の要素を使う場合が増えると、2 番の方法を使うのが、煩わしくなっ てきます。構文上の打開策として、上記の2 行は、
    $arrayref->[0] = "January";
    $hashref->{"KEY} = "VALUE";
    
    のように書くことができます。 矢印の左側は、以前の被参照を含めて、リファレンスを返す任意の式が書けます。 ($array[$x] は、$array->[$x] と同じではありません。)
    $array[$x]->{"foo"}->[0] = "January";
    
    これが、先の左辺値コンテキストで用いると、リファレンスが存在するようにな る、というケースの 1 つです。この文以前には、$array[$x] は未定義 かもしれません。そうならば、自動的にハッシュリファレンスと定義されて、 `{"foo"'} が検索できるようになります。同じように、 $array[$x]->{"foo"}が配列リファレンスで定義され、`[0]' を探 すことができます。 もう一つ。矢印は、括弧付きの添字の「間」では、省略することができますので、 上の例は、
    $array[$x]{"foo"}[0] = "January";
    
    と書くことができます。通常の配列だけを使うように限定すれば、ちょうど C の多次元配列のように使うことができます:
    $score[$x][$y][$z] += 42;
    
    ああ、そうだ、実際には全く C の配列と同じという訳ではありません。C では、 必要に応じて配列を大きくするなどということはできません。Perl では、それ ができます。
  4. リファレンスが、オブジェクトに対するものである場合には、参照されるものを アクセスするためのメソッドがあるはずで、オブジェクトのメソッドを定義する クラスパッケージ内でなければ、そのメソッドを使うようにした方が良いでしょ う。言い換えると、良識をもって、特別正当な理由がない限り、オブジェクトの カプセル化を反古にしてはいけないということです。Perl は、カプセル化を強 要したりはしません。私達は、全体主義者ではありません。ただ、なにがしかの 基本的な節度を期待しています。

ref() 演算子が、リファレンスがどういった型のものを指しているかを、 調べるために使うことができます。See section 組み込み関数,を参照してください。

bless() 演算子は、リファレンスをオブジェクトクラスとして機能する パッケージと組み合わせるために使うことができます。See section オブジェクト,を 参照してください。

被参照構文では、常に目的とするリファレンスの「型」を示すことができますの で、型グロブをリファレンスと同じように被参照することができます。つまり、 ${*foo} と ${\$foo} は、どちらも同じスカラ変数を示すことに なります。

次の例に示すのは、文字列にサブルーティン呼び出しを埋め込む仕掛けです:

print "My sub returned ${\mysub(1,2,3)}\n";

ダブルクォート文字列中に ${...} が見つかると、ブロックとして評価 されます。ブロックでは、mysub(1,2,3) の呼び出しを実行し、その結果 に対するリファレンスがとられます。つまり、ブロック全体では、スカラへのリ ファレンスを返すこととなり、${...} で被参照された後、ダブルクォー ト文字列の中に、はり込まれることになります。


Go to the first, previous, next, last section, table of contents.

検索式: