Что такое анонимные хэши в perl?
$hash = { 'Man' => 'Bill',
'Woman' => 'Mary,
'Dog' => 'Ben'
};
Что именно делает Perl "анонимные хэши"?
Ответы
Ответ 1
Это ссылка на хэш, который может быть сохранен в скалярной переменной. Это как обычный хэш, за исключением того, что фигурные скобки {...}
создают ссылку на хеш.
Обратите внимание на использование разных круглых скобок в следующих примерах:
%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"
Ответ 2
Вы используете анонимный хеш, когда вам нужна ссылка на хэш, и именованный хеш неудобен или ненужен. Например, если вы хотите передать хэш в подпрограмму, вы можете написать
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
, нет общего способа узнать это, и к данным можно получить доступ только по его ссылке.
Ответ 3
Это довольно просто. Они позволяют вам писать
push @hashes, { ... };
f(config => { ... });
вместо
my %hash = ( ... );
push @hashes, \%hash;
my %config = ( ... );
f(config => \%config);
(Если вы хотите узнать цель ссылок, эта другая история полностью.)
Ответ 4
Все, что "анонимно" представляет собой структуру данных, которая используется таким образом, что она не получает имя.
Ваш вопрос путал всех остальных на этой странице, потому что в вашем примере показано, что вы указываете имя созданного хеша, таким образом, оно больше не является анонимным.
Например - если у вас есть подпрограмма, и вы хотите вернуть хэш, вы можете написать этот код: -
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