2013-03-07 7 views
12

関数に渡されるすべての引数が存在する特別な配列@_は、実際に渡された引数のエイリアスです。したがって、この特別な配列@_に直接行った変更は、メインに反映されます。これは明らかです。上記プログラムについてPerl:特別な配列@_は本当にエイリアスではありませんか?

#!/usr/bin/perl 

use warnings; 
use strict; 

$\="\n"; 

sub func { 
     print \@_; 
     $_++ for(@_); 
} 

my @arr=(2..4); 
print \@arr; 
func(@arr); 
print "@arr"; 

、それは別名であるため@arr@_の参照が同じ場所を指すことが期待。しかしそうではありません。上記の実行の

ARRAY(0x1b644d0) 
ARRAY(0x1b644e0) 
3 4 5 

それらが@_で行わ変化が@arrで反射される様子を、2つの異なる位置を指していますか?

私は間違っていますか?ご意見をお聞かせください。

+4

「@ _」は何のエイリアスでもありません。それはドキュメンテーションが言っていることではありません。 '@ _ 'の個々の*要素*はエイリアスです。 –

答えて

17

これは、あなたが質問に答えるかもしれない:見ての通り

use warnings; 
use strict; 

$\="\n"; 

sub func { 
     print \@_; 
     $_++ for(@_); 
     print \$_ for @_; 
} 

my @arr=(2..4); 
print \@arr; 
func(@arr); 
print "@arr"; 
print \$_ for @arr; 

出力

ARRAY(0x17fcba0) 
ARRAY(0x1824288) 
SCALAR(0x17fcc48) 
SCALAR(0x18196f8) 
SCALAR(0x1819710) 
3 4 5 
SCALAR(0x17fcc48) 
SCALAR(0x18196f8) 
SCALAR(0x1819710) 

、個々の引数が同じアドレスを持っていますが、コンテナは同じではありません。 func@_にアイテムをプッシュすると、@arrは変更されません(shiftfunctにすることができます)。したがって、各引数はエイリアスであり、配列要素は個々の項目として渡されます。 @_には、サブルーチンに渡されるすべての項目が含まれます。配列の引数を変更する場合は、参照渡しする必要があります。

+2

ありがとうございました。今日はいくつか素敵なものを聞いてください... – Guru

11

@_はエイリアス化されていません。その要素は次のとおりです。

サブに渡すことができる唯一のことは、スカラーのリストであり、かつ配列はそのリストに評価されるため

func(@arr); 

func($arr[0], $arr[1], ...); 

と同じであることを忘れないでくださいリストコンテキスト内の要素

だから

func(@arr); 

@arrの要素を変化させる@_の要素を変更する基本的

local @_; 
alias $_[0] = $arr[0]; 
alias $_[1] = $arr[1]; 
... 
&func; 

と同じであるが、@_の要素を追加および削除するため@arrを変更しないであろうことを意味しますそれらは異なる配列です。

>perl -E"@a=(4..6); sub { $_[0] = '!';  say @_; }->(@a); say @a;" 
!56 
!56 

>perl -E"@a=(4..6); sub { splice(@_,0,1,'!'); say @_; }->(@a); say @a;" 
!56 
456 
+0

ありがとう池上.... – Guru

+0

改善された例。 – ikegami

関連する問題