2011-02-01 11 views
16

を神秘を解くthis questionでのポスターは1行で次の操作を実行する方法を尋ね SOのローカル僧侶のthis answer 1におけるしかし はPerlのグロブ(*)

sub my_sub { 
    my $ref_array = shift; 
    for (@$ref_array) { 
     #do somthing with $_ here 
    }; 

    #use $ref_array->[$element] here 
} 

提案tchrist:

sub my_sub { 
    local *array = shift(); 
    #use @array here 
} 
01私は中間レベルのPerl 魔法を習得しようとして

を尋ねたところは、私はそれはあなた は何ここに設定されていることが何であるかを、尋ねることができますか? は、渡された 配列参照に@arrayへの参照を設定していますか?どのように @ arrayと%arrayまたは$ arrayを作成していないことを知っていますか? ?ここでは、 について詳しく知ることができます*演算子 (perlop?)。ありがとう!

私は新しい投稿として尋ねるように提案されましたが、彼は素敵な参照をしました。とにかく、ここに行く?誰かが何に割り当てられているかを説明してください。おそらく%arrayまたは$ arrayではなく@arrayがどのように作成されますか?ありがとう。

+0

[この回答](http://stackoverflow.com/questions/3807231/how-can-i-test-if-i-can-write-to-a-からタイプグロブへのいくつかの重要な洞察を集めることができますファイルハンドル/ 4200474#4200474)、ここではまだ触れられていません。 – tchrist

答えて

21

割り当て

*glob = VALUE 

は(すなわち、Scalar::Util::reftype(VALUE)、たとえば、の値を返す)VALUEの種類に依存し、いくつかの魔法が含まれています。 VALUEがスカラー、配列、ハッシュ、またはサブルーチンへの参照である場合、のみがシンボルテーブルのエントリを上書きします。

このイディオムサブルーチンへの最初の引数は配列リファレンスである場合に文書化されているよう

local *array = shift(); 
#use @array here 

作品。最初の引数がスカラー参照ではなく$arrayで、@arrayでない場合は、代入の影響を受けます。

何が起こっているかを見るために少しデモスクリプトは:

no strict; 

sub F { 
    local *array = shift; 

    print "\@array = @array\n"; 
    print "\$array = $array\n"; 
    print "\%array = ",%array,"\n"; 
    print "------------------\n"; 
} 

$array = "original scalar"; 
%array = ("original" => "hash"); 
@array = ("orignal","array"); 

$foo = "foo"; 
@foo = ("foo","bar"); 
%foo = ("FOO" => "foo"); 

F ["new","array"];  # array reference 
F \"new scalar";   # scalar reference 
F {"new" => "hash"};  # hash reference 
F *foo;     # typeglob 
F 'foo';     # not a reference, but name of assigned variable 
F 'something else';  # not a reference 
F();      # undef 

出力:

 
@array = new array 
$array = original scalar 
%array = originalhash 
------------------ 
@array = orignal array 
$array = new scalar 
%array = originalhash 
------------------ 
@array = orignal array 
$array = original scalar 
%array = newhash 
------------------ 
@array = foo bar 
$array = foo 
%array = FOOfoo 
------------------ 
@array = foo bar 
$array = foo 
%array = FOOfoo 
------------------ 
@array = 
$array = 
%array = 
------------------ 
@array = orignal array 
$array = original scalar 
%array = originalhash 
------------------ 

追加ドキュメントperlmodperldataで。参照がPerlの一部となる前の頃、このイディオムは配列とハッシュをサブルーチンに渡すのに役立ちました。

+1

なぜあなたはもはや支配しないのですか? – hobbs

+0

型グロブの代入に対するRHSが型グロブでも参照でもなく文字列でない場合、何が起こるか忘れないでください。 '*' sigilのオペランドが裸ではない文字列であるときにどうなるかを考えてください。最後に、「ローカル」と考える。 – tchrist

+0

この回答が示すように、グロブへの割り当ては参照タイプに応じて異なるスロットを埋めます。あなたは、 'local * array = \ @ {shift @_}'のような適切な型を持つことを綿密に確認することができます。 reference/dereferenceのペア '\ @'は、refが配列の場合は透明ですが、それ以外の場合はエラーを送出します。 –

3

Perlに関する私の知識はあまり知られていませんが、私は答えようとします。 *演算子は、シンボルテーブルエントリを割り当てます。私が理解しているように、@array、%array、および$ arrayはすべて、文字列 'array'の同じシンボルテーブルエントリを参照しますが、そのエントリの異なるフィールドにはARRAY、HASH、およびSCALARフィールドがあります。したがって、local *array = shift;を代入すると、実際には、「配列」(ARRAY、HASH、およびSCALARフィールドを含む)のローカルシンボルテーブルエントリ全体が、呼び出し元で使用されたものに割り当てられます。グロブへ

+1

割り当てられたものがglobまたはglobrefの場合はyesです。それ以外の場合はもっと複雑です。とにかく、シンボルテーブルのエントリは "glob値"を保持する "glob変数"のようなものであり、代入は変数そのものではなく値の部分を設定するため、実際はもっと複雑になります。 – ysth

関連する問題