2012-02-17 33 views
1

配列のハッシュを引数として取るサブルーチンを作成しようとしています。しかし、配列の1つを取得しようとすると、配列自体の代わりに配列のサイズを取得するように見えます。perlのサブルーチンに渡されたハッシュから配列を取り出す方法

my(%hash) = (); 
$hash{"aaa"} = ["blue", 1]; 

_subfoo("test", %hash); 

sub _subfoo { 

    my($test ,%aa) = @_; 

    foreach my $name (keys %aa) { 
     my @array = @{$aa{$name}}; 
     print $name. " is ". @array ."\n"; 
    } 
} 

これは、期待通りに(青、1)の代わりに2を返します。サブルーチンでハッシュの配列を処理する他の方法はありますか?

これは、スタックオーバーフロー、初回ポスター、プログラミング初心者ではあまりにも単純すぎると謝罪します。あなたは右ここスカラーコンテキストにあなたの@array配列を入れている

+1

コードのインデントが非常に乱雑です。 vimなどの自動インデント付きの適切なテキストエディタを使用する必要があります。 – TLP

答えて

10

print $name. " is ". @array ."\n"; 

をスカラーコンテキストでの配列は、あなたの配列の要素数を与え、@arrayは、2つの要素を持っていることを起こります。代わりに次のいずれかを試してください。

print $name . " is " . join(', ', @array) . "\n"; 
print $name, " is ", @array, "\n"; 
print "$name is @array\n"; 

@arrayの要素が表示されます。 joinを使用すると、あなたが好きなように要素をまとめて貼り付けることができます。 2番目はリストコンテキストで@arrayを評価し、値を分けることなく一緒にマッシュします。 3つ目は@arrayの要素を$"(デフォルトでは1つのスペース)と一緒に結合して補間します。

+4

+1。 'print '$ nameは@array \ n"と書くこともできます。これは '@ array'の要素を' $ "'(デフォルトは '' '')で暗黙的に結合します。 – ruakh

+0

@ruakh :ありがとう、あなたのコメントが入っている間、そのオプション(とperldoc.perl.orgのリンク)を追加していました。 –

+0

ありがとう、私はそれを考えなかったでしょう。 – user1215331

4

muが短すぎると言われていますが、スカラーコンテキストで配列を使用したため、要素の代わりにその長さが返されました。私はあなたのコードについての他のいくつかのポインタを持っていました。

これらの引数のうちのいくつかが配列またはハッシュである場合、引数を参照渡しで渡すことは、ときどき考えてください。これは動作します

foo(@bar, @baz); 
sub foo {      # This will not work 
    my (@array1, @array2) = @_; # All the arguments will end up in @array1 
    ... 
} 

、しかし:

foo(\@bar, \@baz); 
sub foo {     
    my ($aref1, $aref2) = @_; 
    ... 
} 

あなたは見つけることが、この理由は、配列やハッシュが、このことは不可能のようなものを作るサブルーチンに渡される前にリストに展開されていることですあなたのケースでは、eachはあなたの目的のための素敵な機能です。

foo("test", \%hash); # note the backslash to pass by reference 

sub foo { 
    my ($test, $aa) = @_; # note use of scalar $aa to store the reference 

    while (my ($key, $value) = each %$aa)) { # note dereferencing of $aa 
     print "$key is @$value\n";   # ...and $value 
    } 
} 
+0

もう一度これはとても良いです。 – user1215331

+0

+1と最初の例に対するコメント:原則としてプロトタイプでは可能ですが、絶対に必要でない限り避けるべきです: 'sub foo(\ @ \ my @ array2 = @ {shift()};} 'foo(@bar、@baz);サブfoo(\ @ \ @){my @ array1 = @ {shift()}; – flesk

関連する問題