25

これを行う方法を理解するのに助けが必要です。私のコード:

my %hash;
$hash{'1'}= {'Make' => 'Toyota','Color' => 'Red',};
$hash{'2'}= {'Make' => 'Ford','Color' => 'Blue',};
$hash{'3'}= {'Make' => 'Honda','Color' => 'Yellow',};


&printInfo(%hash);

sub printInfo{
   my (%hash) = %_;
   foreach my $key (keys %_{       
    my $a = $_{$key}{'Make'};   
    my $b = $_{$key}{'Color'};   
    print "$a $b\n";
    }
}
4

5 に答える 5

40

コードが進化したときに問題を引き起こす可能性がある簡単な方法は、デフォルトの配列 @_ (すべてのキーと値のペアを偶数リストとして含む) を %hash に割り当て、それに従って再構築することです。したがって、コードは次のようになります。

sub printInfo {
   my %hash = @_;
   ...
}

より良い方法は、サブルーチンへの参照としてハッシュを渡すことです。このようにして、サブルーチンにさらに多くのパラメーターを渡すことができます。

printInfo(\%hash);
sub PrintInfo {
   my %hash = %{$_[0]};
   ...
}

Perl で参照を使用するための紹介は、perlreftutにあります。

于 2011-02-04T00:00:10.940 に答える
8

あなたはとても、とても近くにいます。%_ハッシュを渡すための はありません。 で渡す必要があります@_。幸いなことに、ハッシュはリスト コンテキストを使用して割り当てられるため、

sub printInfo {
   my %hash = @_;
   ...
}

それを機能させます!

また、&少なくとも Perl 5.000 以降では、ほとんどの場合、サブルーチン呼び出しの前に in を使用する必要はありませんでした。最近の他の言語と同じように、名前と引数だけで Perl サブルーチンを呼び出すことができます。(@mob がコメントで指摘しているように、これがまだ必要な場合がいくつかあります。興味があれば、これをさらに理解するためにperlsubを参照してください。)

于 2011-02-03T23:54:38.823 に答える
7

ハッシュと配列を渡す最良の方法は、参照渡しです。参照とは、複雑なデータ構造を 1 つのデータ ポイント (スカラー変数( など)に格納できるもの) として扱うための単純な方法$fooです。

参照を読んで、元のデータを取り戻すために参照を作成し、参照を逆参照する方法を理解してください。

非常に基本的なこと: データ構造の前にバックスラッシュを付けて、その構造への参照を取得します。

my $hash_ref   = \%hash;
my $array_ref  = \@array;
my $scalar_ref = \$scalar;   #Legal, but doesn't do much for you...

参照は、元の構造の記憶場所です (および構造に関する手がかり):

print "$hash_ref\n";

次のようなものが出力されます:

HASH(0x7f9b0a843708)

参照を使用可能な形式に戻すには、参照を正しい シジルの前に置くだけです。

my %new_hash = %{ $hash_ref };

これは、Perl で非常に複雑なデータ構造を作成できる方法であり、オブジェクト指向 Perl がどのように機能するかを示すため、参照の使用について学ぶ必要があります。


サブルーチンに 3 つのハッシュを渡したいとしましょう。3 つのハッシュは次のとおりです。

my %hash1 = ( this => 1, that => 2, the => 3, other => 4 );
my %hash2 = ( tom => 10, dick => 20, harry => 30 );
my %hash3 = ( no => 100, man => 200, is => 300, an => 400, island => 500 );

それらの参照を作成します

my $hash_ref1 = \%hash1;
my $hash_ref2 = \%hash2;
my $hash_ref3 = \%hash3;

そして今、参照を渡すだけです:

mysub ( $hash_ref1, $hash_ref2, $hash_ref3 );

参照はスカラーデータであるため、サブルーチンに渡すのに問題はありません。

sub mysub {
    my $sub_hash_ref1  = shift;
    my $sub_hash_ref2  = shift;
    my $sub_hash_ref3  = shift;

今、私はそれらを逆参照するだけで、私のサブルーチンはそれらを使用できます。

    my %sub_hash1 = %{ $sub_hash_ref1 };
    my %sub_hash2 = %{ $sub_hash_ref2 };
    my %sub_hash3 = %{ $sub_hash_ref3 };

refコマンドを使用して、参照が何への参照であるかを確認できます。

my $ref_type = ref $sub_hash_ref;    # $ref_type is now equal to "HASH"

これは、正しいタイプのデータ構造が渡されていることを確認したい場合に便利です。

sub mysub {
    my $hash_ref = shift;

    if ( ref $hash_ref ne "HASH" ) {
        croak qq(You need to pass in a hash reference);
    }

また、これらはメモリ参照であるため、参照を変更すると元のハッシュが変更されることに注意してください。

my %hash = (this => 1, is => 2, a => 3 test => 4);
print "$hash{test}\n";   # Printing "4" as expected
sub mysub ( \%hash );    # Passing the reference
print "$hash{test}\n";   # This is printing "foo". See subroutine:


sub mysub { 
    my $hash_ref = shift;

    $hash_ref->{test} = "foo";    This is modifying the original hash!
}

これは、サブルーチンに渡されたデータを変更できるという良い場合もあれば、元のサブルーチンに渡されたデータを意図せずに変更できるという場合もあります。

于 2013-08-20T17:11:46.103 に答える
6

私はあなたが望むと信じています

my %hash;
$hash{'1'}= {'Make' => 'Toyota','Color' => 'Red',};
$hash{'2'}= {'Make' => 'Ford','Color' => 'Blue',};
$hash{'3'}= {'Make' => 'Honda','Color' => 'Yellow',};

printInfo(%hash);

sub printInfo{
   my %hash = @_;
   foreach my $key (keys %hash){       
    my $a = $hash{$key}{'Make'};   
    my $b = $hash{$key}{'Color'};   
    print "$a $b\n";
   }
}

printInfo(%hash)%hashは、交互のキーと値のペアを含むリストに展開されます。

ではprintInfo@_このリストが割り当てられ%hash、リスト内の代替要素から対応する値を持つキーが再度作成されます。

于 2011-02-03T23:54:39.550 に答える
3

次のように渡すことができます

  1. 引数リストdo_hash_thing( %hash )
  2. 引数リストのハッシュへの参照 `do_hash_thing( @args_before, \%hash, @args_after )
  3. プロトタイプによる参照として、keysおよび他のハッシュ演算子と同様に機能します。

リストは次のように機能します。

sub do_hash_thing {
    my %hash = @_;
    ...
}

do_hash_thing( %hash );

これにより、ハッシュ引数を「ストリーミング」することもできます。

do_hash_thing( %hash_1, %hash_2, parameter => 'green', other => 'pair' );

参照により、次のように機能します。

sub do_hash_thing { 
    my $hash_ref = shift;
    ...
}

do_hash_thing( \%hash, @other_args );

ここでプロトタイプ(\%@)。プロトタイプは、perl が最初の引数でハッシュを探し、それを参照渡しするようにします。

sub do_hash_thing (\%@) { 
    my $hash_ref = shift;
    ...
}

do_hash_thing( %hash => qw(other args) );
# OR
do_hash_thing %hash => qw(other args);

注意: プロトタイプはメソッドでは機能しません。

于 2011-02-04T00:36:33.213 に答える