2009-07-21 13 views
22

Me pidieron que modificara algunos códigos existentes para agregar alguna funcionalidad adicional. He buscado en Google y parece que no puedo encontrar la respuesta. Tengo algo que este efecto ...¿Cómo puedo usar los hashes como argumentos para las subrutinas en Perl?

%first_hash = gen_first_hash(); 
%second_hash = gen_second_hash(); 
do_stuff_with_hashes(%first_hash, %second_hash); 

sub do_stuff_with_hashes 
{ 
    my %first_hash = shift; 
    my %second_hash = shift; 

    # do stuff with the hashes 
} 

estoy consiguiendo los errores siguientes:

Odd number of elements in hash assignment at ./gen.pl line 85. 
Odd number of elements in hash assignment at ./gen.pl line 86. 
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 124. 
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 143. 

Línea 85 y 86 son las dos primeras líneas de la subrutina y 124 y 143 donde estoy accediendo a los hashes. Cuando busco esos errores parece sugerir que mis hash no están inicializados. Sin embargo, puedo verificar que los hash tengan valores. ¿Por qué recibo estos errores?

+1

Se trata de un duplicado. Por favor, eche un vistazo a http://stackoverflow.com/questions/944784/ – innaM

Respuesta

24

Los valores hash se colapsan en listas planas cuando los pasa a la función. Entonces, cuando cambias un valor de los argumentos de la función, solo estás obteniendo un valor. Lo que quiere hacer es pasar los hashes por referencia.

do_stuff_with_hashes(\%first_hash, \%second_hash); 

Pero luego tienes que trabajar con los hashes como referencias.

my $first_hash = shift; 
my $second_hash = shift; 
+0

Ya veo ... Eso hizo el truco ... ¡Muchas gracias! – predhme

5

En primer lugar,

do_stuff_with_hashes(%first_hash, %second_hash); 

"corrientes" los valores hash en una lista, lo que equivale a:

('key1_1', 'value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ...) 

y luego selecciona uno y sólo uno de esos artículos. Así,

my %first_hash = shift; 

es como decir:

my %first_hash = 'key1_1'; 
# leaving ('value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ...) 

no se puede tener un hash como { 'key1' }, ya que es 'key1' mapeo para nada.

+1

Gracias por explicar lo que estaba pasando detrás de escena. – predhme

9

Las referencias hash son el camino a seguir, como han señalado los demás.

Proporcionando otra forma de hacer esto solo por patadas ... porque ¿quién necesita variables de temperatura?

do_stuff_with_hashes({ gen_first_hash() }, { gen_second_hash() }); 

Aquí se acaba de crear referencias de hash sobre la marcha (a través de los corchetes alrededor de las llamadas de función) para utilizar en su función do_stuff_with_hashes. Esto no es nada especial, los otros métodos son igual de válidos y probablemente más claros. Esto podría ayudar en el futuro si ve esta actividad en sus viajes como alguien nuevo en Perl.

+0

¡Gran truco! Mantendré eso. – predhme

+0

Feliz de obligar. Una cosa a tener en cuenta si te quedas en Perl es que todos señalarán cómo "Hay más de una forma de hacerlo". Es una especie de bendición y una maldición) dependiendo de tu opinión sobre tales cosas) en la programación de Perl. ¡Que te diviertas! –

14

Un poco tarde, pero,

Como se ha indicado, se debe pasar referencias, no hashes.

do_stuff_with_hashes(\%first_hash, \%second_hash); 

Pero si necesita/quiere usar sus hashes como tal, puede desreferenciarlos inmediatamente.

sub do_stuff_with_hashes { 
    my %first_hash = %{shift()}; 
    my %second_hash = %{shift()}; 
}; 
+0

para ser claro, no estoy desreferenciando los hashes, los estoy copiando. – larelogio

Cuestiones relacionadas