2009-06-03 14 views
6

私はいくつかの計算を行うと、そのようにように別のサブルーチンにいくつかのプロパティを通過する機能を持っている:Perlでサブルーチンの引数としてハッシュを使用するにはどうすればよいですか?

sub get_result { 
    my $id = 1;  
    my %diet = (result => 28, 
       verdict => 'EAT MORE FRUIT DUDE...'  
       ); 

    my %iq = (result => 193, 
       verdict => 'Professor Einstien' 
      );   
    print_result($id, %diet, %iq); 
} 

sub print_result {  
    my $id = shift;  
    my %d = @_;  
    my %i = @_;  

    print "IQ: $id\n";  
    print "DIET RESULT: $d{result}\n";  
    print "DIET VERDICT: $d{verdict}\n";  
    print "IQ RESULT: $i{result}\n";  
    print "IQ VERDICT: $i{verdict}\n";  
}  

私の問題は、結果は(DIET結果、DIETの判定)及び(IQスコア、IQで印刷ということですRESULT)はどちらも同じです。変数%dと%iに同じ変数が設定されているかのようにこれはなぜですか?

私はそうのような3つのすべての変数のシフトしようとした場合:

my $id = shift;  
my %d = shift;  
my %i = shift; 

を私は次のエラーを取得:あなたは、配列(またはハッシュ)を渡すと

Odd number of elements in hash assignment 

答えて

24

をサブルーチンに、サブルーチンの意志値(またはキー値のペア)のリストを取得します。 2つの配列(または2つのハッシュ)を渡すことができないのは、サブルーチンが最初の配列の終わりと2番目の配列の開始位置を知らないためです。

この問題を回避するには、あなたの代わりに参照を渡す必要があります。

my %hash1 = (foo => 'bar'); 
my %hash2 = (bar => 'baz'); 
subroutine(\%hash1, \%hash2); 

sub subroutine { 
    my ($hashref1, $hashref2) = @_; 
    print $hasref1->{foo}, $hashref2->{bar}; 
} 

PS:%dと%場合

my %d = @_;  
my %i = @_;  

:別に概念的な問題から、あなたのコードもこの特徴私はどちらも同じ値が割り当てられていますが、後で同じときに驚くべきものではありません。あなたのprint_result

+0

これは完璧に機能しました。私は様々なタイプ間の参照を誤解していたと思う。 (Scalar、Array、Hash) ありがとうManni –

+3

あなたがその答えを受け入れると、他の人に役立つかもしれません。 (私は何らかの点で25の評判の点に気づくではありません) – innaM

3

あなたは%diet%iqに渡すと、彼らの両方が引数配列に平らに取得し、そう、%d%diet%iq内のすべての項目が含まれています。解決するために

参照%diet%iq使用:print_resultに続いて

print_result($id, \%diet, \%iq); 

を:

my $id = shift; 
my %d = %{+shift}; 
my %i = %{+shift}; 
+2

あなたの例は、シフトという名前のハッシュを探すつもりです!シフト後に括弧を追加すると、インタープリターは関数呼び出しを望むことができます。 – mkb

+1

%iは空ではありません。両方とも@_から初期化されているため、%dのコピーです。マンニの答えを見てください。 –

+2

これにより、両方のハッシュの浅いコピーが作成されます。つまり、ハッシュの最初のレベルの変更は元のものには表示されませんが、2番目以降のレベルの変更は反映されます。ハッシュは単純なハッシュであるように見えるので、これは今のところうまくいくはずです(ハッシュの変更が伝播しないと思われる限り)。詳細なコピーが必要な場合は、Storableモジュールのdclone関数(http://perldoc.perl.org/Storable.html)を参照してください。 –

0
use strict; 
use warnings; 

sub get_result { 

    ... 

    print_result($id, \%diet, \%iq); 
    # or 
    print_result($id, {%diet}, {%iq}); 
} 


sub print_result{ 
    my($id, $diet_h, $iq_h) = @_; 
    my %diet = %$diet_h; 
    my %iq = %$iq_h; 

    ... 

} 

または:

use strict; 
use warnings; 

sub print_result($\%\%); 

sub get_result{ 

    ... 

    print_result($id, %diet, %iq); 
} 

sub print_result($\%\%){ 
    my($id, $diet_h, $iq_h) = @_; 
    my %diet = %$diet_h; 
    my %iq = %$iq_h; 

    ... 

} 
+2

プロトタイプの答えを最初のものにするのはどうでしょうか? :) –

4

私の本Intermediate Perlを参照してください。そのうち約3分の1は参考文献とその取り扱い方法を扱っています。これには、複雑なデータ構造をサブルーチンに渡すだけでなく、参照があなたの人生をより容易にする他の方法も含まれます。 :)

some_sub(\%hash); 
some_sub({ key => 'value' }); 
some_sub($hash_ref); 

sub some_sub { 
    my($hash_ref) = @_; 

    ... 
    } 
関連する問題