$hash = { 'Man' => 'Bill',
'Woman' => 'Mary,
'Dog' => 'Ben'
};
Что именно делает Perl "анонимные хэши"?
$hash = { 'Man' => 'Bill',
'Woman' => 'Mary,
'Dog' => 'Ben'
};
Что именно делает Perl "анонимные хэши"?
Это ссылка на хэш, который может быть сохранен в скалярной переменной. Это как обычный хэш, за исключением того, что фигурные скобки {...}
создают ссылку на хеш.
Обратите внимание на использование разных круглых скобок в следующих примерах:
%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"
Вы используете анонимный хеш, когда вам нужна ссылка на хэш, и именованный хеш неудобен или ненужен. Например, если вы хотите передать хэш в подпрограмму, вы можете написать
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 cat" };
намного опрятно, чем
my %newperson = ( age => 4, position => "ship cat" );
$crew{jess} = \%newperson;
и, конечно, даже если хэш создается с именем, если его ссылка передается в другом месте, тогда не может быть использование этого исходного имени, поэтому оно должно рассматриваться как анонимное. Например, в
my $crew_member = $crew{bill}
$crew_member
теперь фактически является ссылкой на анонимный хеш, независимо от того, как данные были первоначально созданы. Даже если данные (в некоторой области) все еще доступны как %person1
, нет общего способа узнать это, и к данным можно получить доступ только по его ссылке.
Это довольно просто. Они позволяют вам писать
push @hashes, { ... };
f(config => { ... });
вместо
my %hash = ( ... );
push @hashes, \%hash;
my %config = ( ... );
f(config => \%config);
(Если вы хотите узнать цель ссылок, эта другая история полностью.)
Все, что "анонимно" представляет собой структуру данных, которая используется таким образом, что она не получает имя.
Ваш вопрос путал всех остальных на этой странице, потому что в вашем примере показано, что вы указываете имя созданного хеша, таким образом, оно больше не является анонимным.
Например - если у вас есть подпрограмма, и вы хотите вернуть хэш, вы можете написать этот код: -
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"]);'
[email protected] = [
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