web-dev-qa-db-ja.com

Perlのサブルーチンへの引数としてハッシュを使用するにはどうすればよいですか?

いくつかの機能を追加するために、いくつかの既存のコードを変更するように求められました。 Googleで検索しましたが、答えが見つからないようです。私はこの効果に何かを持っています...

%first_hash = gen_first_hash();
%second_hash = gen_second_hash();
do_stuff_with_hashes(%first_hash, %second_hash);

sub do_stuff_with_hashes
{
    my %first_hash = shift;
    my %second_hash = shift;

    # do stuff with the hashes
}

次のエラーが発生します。

Odd number of elements in hash assignment at ./gen.pl line 85.
Odd number of elements in hash assignment at ./gen.pl line 86.
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 124.
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 143.

行85と86は、サブルーチンの最初の2行であり、124と143は、ハッシュにアクセスしている場所です。これらのエラーを調べると、ハッシュが初期化されていないことが示唆されているようです。ただし、ハッシュに値があることを確認できます。なぜこれらのエラーが発生するのですか?

25
user130532

ハッシュを関数に渡すと、ハッシュはフラットリストに折りたたまれます。したがって、関数の引数から値をシフトオフすると、取得する値は1つだけになります。あなたがしたいのは、参照によってハッシュを渡すことです。

do_stuff_with_hashes(\%first_hash, \%second_hash);

ただし、ハッシュを参照として使用する必要があります。

my $first_hash  = shift;
my $second_hash = shift;
26
Mark Canlas

少し遅いですが、

すでに述べたように、ハッシュではなく参照を渡す必要があります。

do_stuff_with_hashes(\%first_hash, \%second_hash);

ただし、ハッシュをそのように使用する必要がある/使用したい場合は、すぐにそれらを逆参照することができます。

sub do_stuff_with_hashes {
    my %first_hash = %{shift()};
    my %second_hash = %{shift()};
};
16
larelogio

他の人が指摘しているように、ハッシュ参照は進むべき道です。

キックのためだけにこれを行う別の方法を提供します...誰が一時変数を必要とするのですか?

do_stuff_with_hashes( { gen_first_hash() }, { gen_second_hash() } );

ここでは、do_stuff_with_hashes関数で使用するハッシュ参照を(関数呼び出しを中括弧で囲んで)その場で作成しているだけです。これは特別なことではありません。他の方法も同様に有効で、おそらくより明確です。旅行中にこのアクティビティをPerlの初心者として見た場合、これは将来的に役立つ可能性があります。

9
Kyle Walsh

最初に、

 do_stuff_with_hashes(%first_hash, %second_hash);

次と同等のハッシュをリストに「ストリーミング」します。

 ( 'key1_1', 'value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ... )

次に、それらのアイテムを1つだけ選択します。そう、

 my %first_hash = shift;

言っているようなものです:

 my %first_hash = 'key1_1'; 
 # leaving ( 'value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ... )

{ 'key1' }は何にもマッピングされていないため、'key1'のようなハッシュを持つことはできません。

7
Axeman