2012-05-22 17 views
6

質問1:どのようにして配列をPerlの関数に渡すことができますか?

私は関数に配列を渡したいと思います。しかし、渡された引数は関数内で変更されます。それは価値によって呼び出されますか?

質問2:

#my ($name, $num, @array)= @_; <=1) 
my $name = shift;    <=2) 
my $num = shift; 
my @array = shift; 

ケース1と2は、異なる出力を持っています。なぜそれが起こったのですか?以下は

#!/usr/bin/perl 
use strict; 

my @test1; 
push @test1, ['a', 1]; 
push @test1, ['b', 1]; 
push @test1, ['c', 1]; 
push @test1, ['d', 1]; 
push @test1, ['e', 1]; 

for (my $i=0; $i< scalar(@test1); $i++) { 
    print "out1: $test1[$i][0] $test1[$i][1]\n"; 
} 

test_func("test_func", 10, @test1); 

sub test_func { 
    #my ($name, $num, @array)= @_; <=1) 
    my $name = shift;    <=2) 
    my $num = shift; 
    my @array = shift; 

    print "$name\n"; 
    print "$num\n"; 

    for (my $i=0; $i< scalar(@test1); $i++) { 
     print "$array[$i][0] $array[$i][1]\n"; 
    } 

    for (my $i=0; $i< scalar(@test1); $i++) { 
     if ($array[$i][0] eq 'a') { 
      $array[$i][0] = 'z'; 
     } 
    } 
    for (my $i=0; $i< scalar(@test1); $i++) { 
     print "change: $array[$i][0] $array[$i][1]\n"; 
    } 
} 

for (my $i=0; $i< scalar(@test1); $i++) { 
    print "out2: $test1[$i][0] $test1[$i][1]\n"; 
} 

テスト出力です。

out1: a 1 
out1: b 1 
out1: c 1 
out1: d 1 
out1: e 1 
test_func 
10 
a 1 
b 1 
c 1 
d 1 
e 1 
change: z 1 
change: b 1 
change: c 1 
change: d 1 
change: e 1 
out2: z 1 <= Why did it change? 
out2: b 1 
out2: c 1 
out2: d 1 
out2: e 1 

答えて

10
私は関数[...]に配列を渡したいと思います。出力が異なります。なぜそれが起こったのですか?

関数 subに配列を渡すことはできません。サブは引数としてスカラのリストしか取ることができません。

test_func("test_func", 10, @test1); 

あなたは

my ($name, $num, @array) = @_; 

shiftを行うときは、test_funcで新しい配列を作成している

test_func("test_func", 10, $test1[0], $test1[1], $test1[2], $test1[3], $test1[4]); 

と同じである必然スカラーである、@_の最初の要素を返します。 @_は配列であり、配列の要素はスカラーです。等価となるのは

my $name = shift(@_); 
my $num = shift(@_); 
my @array = splice(@_); 

です。配列をサブに渡すには、通常、その配列への参照を渡します。

test_func("test_func", 10, \@test1); 

my ($name, $num, $array) = @_; 

my $name = shift; 
my $num = shift; 
my $array = shift; 

say "@$array"; 

しかし、渡された引数は、関数内で変更されました。それは価値によって呼び出されますか?

Perlは値渡しません。常に参照渡し。 @_の要素を変更すると、呼び出し元の対応する引数が変更されます。

$ perl -E'sub f { $_[0] = "def"; } my $x = "abc"; f($x); say $x;' 
def 

しかし、それは問題ではありません。 @_の要素は変更しません。あなたがやっているのは、$test[0]$array[0]の両方で参照される単一の配列を変更することです。

my $ref1 = [ 'a', 1 ]; # aka $test1[0] 
my $ref2 = $ref1;  # aka $array[0] 
$ref2->[0] = 'z';  # Changes the single array (not $ref1 or $ref2). 

my @anon = ('a', 1); 
my $ref1 = \@anon;  # aka $test1[0] 
my $ref2 = $ref1;  # aka $array[0] 
$ref2->[0] = 'z';  # Changes @anon (not $ref1 or $ref2). 

Storabledcloneは、アレイの 『ディープコピー』を作るために使用することができるためにそれは短いです:

これは、あなたがやっていることです。

my $ref1 = [ 'a', 1 ]; 
my $ref2 = dclone($ref1); # clones the reference, the array, 'a' and 1. 
$ref1->[0] = 'y';   # Changes the original array 
$ref2->[0] = 'z';   # Changes the new array 
+0

種類の説明をお願い致します。私の困難な問題を解決します^^ – user1395438

+0

この解決策が助けになった場合は、その隣にあるチェックマークを –

+0

にしてください。もし見つからなければ、何が欠けているか教えてください。 – ikegami

関連する問題