¿Qué son los hashes anónimos en perl?
data-structures perl-data-structures (4)
Es una referencia a un hash que se puede almacenar en una variable escalar. Es exactamente como un hash regular, excepto que los corchetes {...}
crean una referencia a un hash.
Tenga en cuenta el uso de diferentes paréntesis en estos ejemplos:
%hash = ( foo => "bar" ); # regular hash
$hash = { foo => "bar" }; # reference to anonymous (unnamed) hash
$href = /%hash; # reference to named hash %hash
Esto es útil para poder hacer, si, por ejemplo, desea pasar un hash como argumento a una subrutina:
foo(/%hash, $arg1, $arg2);
sub foo {
my ($hash, @args) = @_;
...
}
Y es una forma de crear un hash multinivel:
my %hash = ( foo => { bar => "baz" } ); # $hash{foo}{bar} is now "baz"
$hash = { ''Man'' => ''Bill'',
''Woman'' => ''Mary,
''Dog'' => ''Ben''
};
¿Qué hacen exactamente los "hashes anónimos" de Perl?
Es bastante simple. Te permiten escribir
push @hashes, { ... };
f(config => { ... });
en lugar de
my %hash = ( ... );
push @hashes, /%hash;
my %config = ( ... );
f(config => /%config);
(Si quiere saber el propósito de las referencias, esa es otra historia por completo).
Utiliza un hash anónimo cuando necesita referencia a un hash y un hash con nombre es inconveniente o innecesario. Por ejemplo, si quisiera pasar un hash a una subrutina, podría escribir
my %hash = (a => 1, b => 2);
mysub(/%hash);
pero si no hay necesidad de acceder al hash a través de su nombre %hash
, podría escribir de manera equivalente
mysub( {a => 1, b => 2} );
Esto es útil donde sea que necesite una referencia a un hash, y particularmente cuando está construyendo estructuras de datos anidados. En lugar de
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,
);
puedes escribir solo
my %crew = (
bill => { age => 34, position => ''captain'' },
ben => { age => 28, position => ''boatswain'' },
weed => { age => 18, position => ''cabin boy'' },
);
y para agregar un miembro,
$crew{jess} = { age => 4, position => "ship''s cat" };
es mucho más limpio que
my %newperson = ( age => 4, position => "ship''s cat" );
$crew{jess} = /%newperson;
y, por supuesto, incluso si se crea un hash con un nombre, si su referencia se pasa a otra parte, es posible que no haya forma de usar ese nombre original, por lo que debe tratarse como anónimo. Por ejemplo, en
my $crew_member = $crew{bill}
$crew_member
ahora es efectivamente una referencia a un hash anónimo, independientemente de cómo se construyeron originalmente los datos. Incluso si los datos son (en algún ámbito) todavía accesibles como %person1
no hay una forma general de saber eso, y solo se puede acceder a los datos por su referencia.
Cualquier cosa "anónima" es una estructura de datos que se usa de forma tal que no obtiene un nombre.
Su pregunta ha confundido a todos los demás en esta página, porque su ejemplo muestra que le da un nombre al hash que ha creado, por lo que ya no es anónimo.
Por ejemplo, si tiene una subrutina y desea devolver un hash, puede escribir este código:
return {''hello''=>123};
ya que no tiene nombre allí - es anónimo. Siga leyendo para aclarar la confusión adicional que otras personas han agregado en esta página mediante la introducción de referencias, que no son lo mismo.
Este es otro hash anónimo (uno vacío):
{}
Este es un hash anónimo con algo en él:
{''foo''=>123}
Esta es una matriz anónima (vacía):
[]
Esta es una matriz anónima con algo en ella:
[''foo'',123]
La mayoría de las veces, cuando las personas usan estas cosas, realmente están tratando de ponerlas mágicamente dentro de otras estructuras de datos, sin la molestia de darles un nombre temporal inútil cuando hacen esto.
Por ejemplo, es posible que desee tener un hash en el medio de una matriz.
@array=(1,2,{foo=>3});
esa matriz tiene 3 elementos: ¡el último elemento es un hash! ($ array [2] -> {foo} es 3)
perl -e ''@array=(1,2,{foo=>1});use Data::Dumper;print Data::Dumper->Dump([/@array],["/@array"]);''
$@array = [
1,
2,
{
''foo'' => 1
}
];
A veces no desea pasar una estructura de datos completa, en su lugar, solo desea utilizar un puntero o referencia a la estructura de datos. En Perl, puede hacer esto agregando una "/" delante de una variable;
%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 $$)
Si estás loco, incluso puedes tener referencias a hashes anónimos:
perl -e ''print [],/[],{},/{}''
ARRAY(0x10eed48)REF(0x110b7a8)HASH(0x10eee38)REF(0x110b808)
y, a veces, Perl es lo suficientemente astuto como para saber que realmente quería decir referencia, incluso cuando no lo dijo específicamente, como mi primer ejemplo de "devolución":
perl -e ''sub tst{ return {foo=>bar}; }; $var=&tst();use Data::Dumper;print Data::Dumper->Dump([/$var],["/$var"]);''
$var = /{
''foo'' => ''bar''
};
o:-
perl -e ''sub tst{ return {foo=>bar}; }; $var=&tst(); print "$$var{foo}/n$var->{foo}/n"''
bar
bar