2

なぜこれが機能するのですか?つまり2行目です

DB<1> $a = {'a'=>1}; $b = {'a'=>2, 'b'=>0};
DB<2> $c = ($a, $b);
DB<3> print $c;
  HASH(0x8743e68)
DB<4> print $c->{a},$c->{b};
  20

%$ aと%$ bを注意深く使用すれば、perlは私が何を意味するのかを理解するだろうと理解していますが、リストに裸の参照があるだけで、なぜそれが機能するのですか?

それとも、それが機能しているように見えて、私は本当に何か他のことをしましたか?

4

1 に答える 1

13

にリストコンテキストはありません

$c = ($a, $b);

代わりに、表示されているのは、動作中のコンマ演算子です。

バイナリ「、」はコンマ演算子です。スカラーコンテキストでは、左側の引数を評価し、その値を破棄してから、右側の引数を評価してその値を返します。これは、Cのコンマ演算子と同じです。

これをより明確に確認するには、以下を参照してください。

#!/usr/bin/perl
use strict; use warnings;

my $x = {a => 1};
my $y = {a => 2, b => 0};

my $z = ($x, $y);

print "\$x = $x\t\$y = $y\t\$z = $z\n";

my @z = ($x, $y);
print "@z\n";

まず、警告を使用しました。したがって、このスクリプトを実行すると、次の警告が表示されます。

Useless use of private variable in void context at C:\Temp\t.pl line 7.

常に警告を有効にしてください。

これで、出力に何が起こっているかが表示されます。

$ x = HASH(0x39cbc)$ y = HASH(0x39dac)$ z = HASH(0x39dac)
HASH(0x39cbc)HASH(0x39dac)

明らかに、$zと同じ匿名ハッシュを指し$yます。値のコピーは行われませんでした。

また、 doと$z[0]同じ匿名ハッシュを参照し、do$xとと同じ匿名ハッシュを参照します。$z[1]$y$z

括弧だけではリストコンテキストは作成されないことに注意してください。の場合

my @z = ($x, $y);

=コンマ演算子よりも緊密にバインドされるため、これらが必要です。

my @z = $x, $y;

に割り当て$x$z[0]破棄$yします(そして警告を発します)が、

my @z = 1 .. 5;

期待どおりに動作します。

最後に、との両方が指す$z匿名ハッシュのコピーを含む新しい匿名ハッシュに割り当てる場合は、次のようにします。$x$y

#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper;

my $x = {a => 1};
my $y = {a => 2, b => 0};

my $z = { %$x, %$y };

print Dumper $z;

これは出力します:

$ VAR1 = {
          'a' => 2、
          'b' => 0
        };

ハッシュキーは、定義上、一意であるためです。両方のハッシュのキーに関連付けられているすべての値を保持する場合は、もう少し複雑なことを行う必要があります(「ユニオン」ハッシュの値として匿名のarrayrefを使用します)。

#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper;

my $x = {a => 1};
my $y = {a => 2, b => 0};

my $z;

push @{ $z->{$_} }, $x->{$_} for keys %$x;
push @{ $z->{$_} }, $y->{$_} for keys %$y;

print Dumper $z;

出力:

VAR1 = {
         'a' => [
                  1、
                  2
                ]、
         'b' => [
                  0
                ]
       };
于 2010-12-16T21:59:40.983 に答える