2011-12-12 8 views
9

に参照することによりハッシュを渡すために、私は、これはperlのの些細な使用はもちろんのこと、Googleで簡単に検索する必要があります知っているが、私は私が見つけた、彼らのこれまでのところ何も与えない多くのソリューションを試してみました予想される行動。基本的に、私は次のようなコードを経由して、サブルーチンを呼び出すことサブルーチンからハッシュへの参照を返す、別のサブルーチンにそのハッシュへの参照を渡すと、そのハッシュの内容を印刷しようとしている:どのようにperlの

#!/usr/bin/perl                                                 

my $foo = make_foo(); 

foreach $key (sort keys %$foo) { 
    print "2 $key $$foo{$key}\n"; 
} 

print_foo(\%foo); 

sub print_foo 
{ 
    my %loc = ???; 
    foreach $key (sort keys %loc}) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 

sub make_foo 
{ 
    my %ret; 
    $ret{"a"} = "apple"; 
    foreach $key (sort keys %ret) { 
     print "1 $key $ret{$key}\n"; 
    } 
    return \%ret; 
} 

誰かが私にハッシュの余分なコピーを作成せずに(サブルーチンを経​​由して)これを行うための最善の方法を教えてください。私が試した解決策では、 "3"で始まる行は表示されませんでした。

+8

私はあなたのコードの先頭に 'use strict'を使用することを強くお勧めします。 'my'を使って変数を宣言するために' foreach'行を変更する必要がありますが、単純な入力ミスをデバッグする多くの頭痛を軽減します。よりよい '%と書かれた – zostay

答えて

10

sub print_foo 
{ 
    my ($loc) = @_; 
    foreach my $key (sort keys %$loc) { 
     print "3 $key $loc->{$key}\n"; 
    } 
} 

あなたが言及していつでも、あなたは明示的に間接参照する必要があります。また、参照の変更によってオリジナルが変更されることにも注意してください。あなたは、元を変更しないようにしたい場合は、リストとしてハッシュを渡すことができ、次のいずれか

print_foo(%foo); # flattens the hash to a list and passes it in through @_ 

sub print_foo 
{ 
    my (%loc) = @_; # load the hash from the list 
    foreach my $key (sort keys %loc) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 

たり、新しいハッシュにハッシュリファレンスをコピーします。

sub print_foo 
{ 
    my ($ref_loc) = @_; # changes to %$ref_loc will change %foo 
    my %loc = %$ref_loc; # COPY, changes to %loc do not change %foo 
    foreach my $key (sort keys %loc}) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 
-1

あなたがそうのようなハッシュへのリファレンスからその変換したい:

my %loc = %{@_[0]}; 

または

my %loc = %{shift}; 

あなたはまた、参考として、それを維持することができます:

my $locref = shift; 
foreach $key (sort keys %$locref}) { 
    print "3 $key $locref->{$key}\n"; 
} 

このコマンドラインでperldoc perlrefと入力すると、情報が見つかります。あなたは、参照としてのパラメータを引き出し、それを逆参照する必要が

+4

単一の要素スライス{$ _ [0]}'、 '%{シフト}' 'shift'、あなたはおそらく意味'%{+シフト} 'や'%{シフトという名前のハッシュ変数を参照しています@_} '。名前付きループ変数は、 'foreach my $ key ... ... 'でなければなりません。 –

+0

すべてのカウントを修正してください。 – Dan

3

他のすべてが良いですので、私ただ

sub print_foo 
{ 
    my %loc = %{shift @_}; 
    foreach $key (sort keys %loc) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 

FYI ... print_fooに集中するつもり、あなたが(:Confusion about proper usage of dereference in Perl私はここにこれを説明して質問を)%のLOCは、現在ハッシュのコピーであることを認識する必要があります。コピーを避けるために...

sub print_foo 
{ 
    my $loc = shift @_; 
    foreach $key (sort keys %$loc) { 
     my $val = $loc->{$key} 
     print "3 $key $val\n"; 
    } 
} 
関連する問題