2012-02-20 10 views
3
#!/usr/bin/perl 

    A(); 
    B(); 

    sub A { 
     my @array = qw(value_1 value_2); 
     $array_ref = \@array; 
    } 

    sub B { 
     foreach my $i (@{$array_ref}) { 
      print "Array Value: $i \n"; 
     } 
    } 

配列は 'my'キーワードを使用して宣言されているため、配列参照が失われる可能性がありますか? 誰でもこのことを私に簡単に伝えることができます。このサンプルコードでは、配列参照のスコープは重要です

答えて

7

いいえ、変数の有効範囲は失効しますが、メモリアドレスは失効しません。データはそのまま残ります。

これは単純に試したことがありますか? =)私はあなたのコードをコピー/ペーストして試してみましたが、うまくいきました。

適切なカプセル化のために、しかし、あなたは本当に代わりに配列リファレンスを返す必要があります:

B(A()); 
# Or 
my $aref = A(); 
B($aref); 

sub A { 
     my @array = qw(value_1 value_2); 
     return \@array; 
} 

sub B { 
    my $array_ref = shift; 
    foreach my $i (@$array_ref) { 
     print "Array Value: $i \n"; 
    } 
} 
3

私は間違いなく(非常に最初にそれを置く)Perlスクリプトで

use strict; 

を使用することをお勧めします。この場合、$ array_refが宣言されていないグローバルなことについて文句を言います。おそらく、混乱の主な原因は、$ array_refを何も宣言せずに使用するため、グローバル変数として扱われます。

この非常に変数によって参照されるため、配列の内容自体は保持されるため、参照カウントは0より大きくなります(perlは内部で変数を削除するために参照カウントを使用します)。

もちろん、TLP投稿(グローバルなし)のようなアプローチが推奨されます。

0

実際には、この例ではmyを使用する非常に良い理由があります。
実際には、サブルーチンで毎回変数を再作成する必要があります。そうしないと、以前に取得した値が変更されます。 @arrayのすべてのコピーが同一であるか

use strict; 
use warnings; 
use 5.10.1; 

my @array; 
sub A{ 
    push @array, scalar @array; # add the length of @array to the end 
    return \@array; 
} 

my @list; 

for('A'..'D'){ 
    my $current = A(); 
    push @list, $current; 
    say join ' ', @$current; 
} 

say ''; 

say join ' ', @$_ for @list; 
0 
0 1 
0 1 2 
0 1 2 3 

0 1 2 3 
0 1 2 3 
0 1 2 3 
0 1 2 3 

注意してください。


この理由から、サブルーチンが呼び出されるたびに新しいコピーが必要です。

use strict; 
use warnings; 
use 5.10.1; 

sub A{ 
    state $iter = 0; 
    my @array; 
    push @array, 0..$iter++; 
    return \@array; 
} 

my @list; 

for('A'..'D'){ 
    my $current = A(); 
    push @list, $current; 
    say join ' ', @$current; 
} 

say ''; 

say join ' ', @$_ for @list; 
0 
0 1 
0 1 2 
0 1 2 3 

0 
0 1 
0 1 2 
0 1 2 3 
関連する問題