web-dev-qa-db-ja.com

Perlの匿名ハッシュとは何ですか?

$hash = { 'Man' => 'Bill',
          'Woman' => 'Mary,
          'Dog' => 'Ben'
        };

Perlの「匿名ハッシュ」は正確に何をしますか?

17
user1363308

これは、スカラー変数に格納できるハッシュへの参照です。中括弧{...}がハッシュへの参照を作成することを除いて、通常のハッシュとまったく同じです。

これらの例では、さまざまな括弧の使用法に注意してください。

%hash = ( foo => "bar" );   # regular hash
$hash = { foo => "bar" };   # reference to anonymous (unnamed) hash
$href = \%hash;             # reference to named hash %hash

これは、たとえばハッシュを引数としてサブルーチンに渡したい場合に実行できると便利です。

foo(\%hash, $arg1, $arg2);

sub foo {
    my ($hash, @args) = @_;
    ...
}

そして、それはマルチレベルハッシュを作成する方法です:

my %hash = ( foo => { bar => "baz" } );  # $hash{foo}{bar} is now "baz"
19
TLP

ハッシュへの参照が必要で、名前付きハッシュが不便または不要な場合は、匿名ハッシュを使用します。たとえば、サブルーチンにハッシュを渡したい場合は、次のように記述できます。

my %hash = (a => 1, b => 2);
mysub(\%hash);

ただし、名前%hashを介してハッシュにアクセスする必要がない場合は、同等に次のように記述できます。

mysub( {a => 1, b => 2} );

これは、ハッシュへの参照が必要な場合、特にネストされたデータ構造を構築する場合に便利です。の代わりに

my %person1 = ( age => 34, position => 'captain' );
my %person2 = ( age => 28, position => 'boatswain' );
my %person3 = ( age => 18, position => 'cabin boy' );

my %crew = (
  bill => \%person1,
  ben  => \%person2,
  weed => \%person3,
);

あなたはただ書くことができます

my %crew = (
  bill => { age => 34, position => 'captain' },
  ben  => { age => 28, position => 'boatswain' },
  weed => { age => 18, position => 'cabin boy' },
);

メンバーを追加するには、

$crew{jess} = { age => 4, position => "ship's cat" };

よりもずっときれいです

my %newperson = ( age => 4, position => "ship's cat" );
$crew{jess} = \%newperson;

もちろん、ハッシュが名前で作成されたとしても、その参照が他の場所に渡された場合、その元の名前を使用する方法がない可能性があるため、匿名として扱う必要があります。たとえば、

my $crew_member = $crew{bill}

$crew_memberは、データが最初にどのように構築されたかに関係なく、事実上匿名ハッシュへの参照になりました。データが(ある範囲で)%person1としてアクセス可能であっても、それを知る一般的な方法はなく、データはその参照によってのみアクセスできます。

12
Borodin

とても簡単です。彼らはあなたが書くことを可能にします

Push @hashes, { ... };

f(config => { ... });

の代わりに

my %hash = ( ... );
Push @hashes, \%hash;

my %config = ( ... );
f(config => \%config);

(参照の目的を知りたい場合、それはまったく別の話です。)

5
ikegami

「匿名」とは、名前を取得しない方法で使用されるデータ構造です。

あなたの質問は、このページの他のすべての人を混乱させました。あなたの例は、作成したハッシュに名前を付けることを示しているため、匿名ではなくなりました。

たとえば、サブルーチンがあり、ハッシュを返したい場合は、次のコードを記述できます。

return {'hello'=>123};

そこには名前がないので、匿名です。同じことではない参照を紹介することによって、他の人々がこのページに追加した余分な混乱をほどくために読んでください。

これは別の匿名ハッシュ(空のハッシュ)です:

{}

これは、何かが含まれている匿名のハッシュです。

{'foo'=>123}

これは匿名の(空の)配列です:

[]

これは、何かが含まれている匿名の配列です。

['foo',123]

人々がこれらのものを使用するほとんどの場合、彼らは実際にそれらを他のデータ構造の中に魔法のように入れようとしています。これを行うときに時間の無駄な一時的な名前を付けることはありません。

たとえば、配列の途中にハッシュを配置したい場合があります。

@array=(1,2,{foo=>3});

その配列には3つの要素があります-最後の要素はハッシュです! ($ array [2]-> {foo}は3です)

Perl -e '@array=(1,2,{foo=>1});use Data::Dumper;print Data::Dumper->Dump([\@array],["\@array"]);'
$@array = [
            1,
            2,
            {
              'foo' => 1
            }
          ];

データ構造全体を渡したくない場合があります。代わりに、ポインタまたはデータ構造への参照を使用するだけです。 Perlでは、変数の前に「\」を追加することでこれを行うことができます。

%hashcopy=%myhash;     # this duplicates the hash
$myhash{test}=2;       # does not affect %hashcopy
$hashpointer=\%myhash; # this gives us a different way to access the same hash
$hashpointer->{test}=2;# changes %myhash
$$hashpointer{test}=2; # identical to above (notice double $$)

あなたが夢中なら、匿名のハッシュへの参照を持つことさえできます:

Perl -e 'print [],\[],{},\{}'
ARRAY(0x10eed48)REF(0x110b7a8)HASH(0x10eee38)REF(0x110b808)

そして時々、Perlはあなたが本当にあなたを知るのに十分賢いです意味私の最初の「リターン」の例のように、あなたが特にそう言わなかったとしても、参照:

Perl -e 'sub tst{ return {foo=>bar}; }; $var=&tst();use Data::Dumper;print Data::Dumper->Dump([\$var],["\$var"]);'     
$var = \{
       'foo' => 'bar'
     };

または:-

Perl -e 'sub tst{ return {foo=>bar}; }; $var=&tst(); print "$$var{foo}\n$var->{foo}\n"'
bar
bar
3
cnd