2010-10-18 15 views
5

Tengo el siguiente (idealizado de un insecto) script cortos en Perl:¿Por qué mi hash no es undef?

my %metadata = undef; 
if (defined %metadata) 
{ 
    print "defined"; 
} 

Por alguna razón, la salida del programa siempre está "definido". Por lo tanto, establecer el hash para que sea "indefinido" de alguna manera lo define. ¿Se define como "indefinido"?

EDIT:

Este es un caso idealizado, en un intento de reproducir el problema. Lo que estoy haciendo realmente es más como:

my %metadata = my_sub_function(); 
if (defined %metadata) 
{ 
    print "defined"; 
} 

donde la salida de my_sub_function puede ser undef,() o un hash poblada, y sólo desea imprimir "definido" en el último de estos casos.

EDIT 2:

Incidentalmente he encontrado que

if (scalar(keys %metadata) 

comporta correctamente para(), pero todavía no para undef.

+3

¿el '' my_sub_function' hacer un retorno a undef' i ndicar el fracaso o no hay datos? Si es así, probablemente debería hacer un 'retorno' desnudo en su lugar. Eso se interpretaría como 'undef' en el contexto escalar y'() '(la lista vacía) en el contexto de la lista. –

Respuesta

8

Si su función devuelve undef y que no def se coloca en los cambios de hash, auto-stringification que UNDEF ser '' y termina con: %metadata = ('' => undef).

Si su función necesita para volver ya sea undef, () o un hash adecuada y que necesita para poner a prueba los tres casos por separado, sugeriría:

my %metadata = my_sub_function(); 
if (!scalar keys %metadata) { 
    print "An empty list() was returned\n" 
} elsif (
    scalar keys %metadata == 1 and 
    exists $metadata{''} and 
    !defined $metadata{''} 
) { 
    print "undef or '' was returned\n"; 
} else { 
    print "A hash was hopefully returned\n"; 
} 

podría probar con los siguientes my_sub_functions :

sub my_sub_function { return()     } # 1st case 
sub my_sub_function { return undef    } # 2nd case 
sub my_sub_function { return (a => 1, b => 2) } # 3rd case 
sub my_sub_function { return qw/not a hash/  } # unhandled case 

feliz piratería

+1

Maravilloso; ¡muchas gracias! Perl siempre me atrapa con cuán fácil es hacer algunas cosas difíciles, y cuán difíciles se vuelven algunas cosas que deberían ser simples :) –

8

Trate

my %metadata; 
undef %metadata; 
if (defined %metadata) 
{ 
    print "defined"; 
} 

creo que sólo estaba usando un "undef" como datos para poblar el hash.

"advertencias utiliza las" habrían dicho:

defined(%hash) is deprecated at t.pl line 6. 
    (Maybe you should just omit the defined()?) 
Odd number of elements in hash assignment at t.pl line 4. 
Use of uninitialized value in list assignment at t.pl line 4. 

undef,() o un hash poblada

Si realmente quiere distinguir entre un hash vacía y sin hachís, mejor use una referencia hash (también más clara para pasar de la subrutina, sin pasar por copiar y todo).

+0

¡ah, interesante! No he visto este error en mis registros, y el código del que proviene sí usa terminante y usa advertencias. También lo intenté sin definir (% hash), con los mismos resultados. –

+0

desafortunadamente no estoy a cargo de lo que vuelve directamente de la función secundaria, así que tengo que trabajar con lo que me dieron :) –

+0

"El uso de los definidos en los agregados (hash y matrices) está obsoleto. si alguna vez se ha asignado memoria para ese agregado. Este comportamiento puede desaparecer en versiones futuras de Perl. En su lugar, debe usar una prueba simple para el tamaño ". Por lo tanto, su enfoque actual podría no funcionar demasiado bien. Mejor hablar con las personas que hicieron esa subrutina. – Thilo

1

probar esto

%metadata=("1"=>"one"); 
undef %metadata; 
if (%metadata) 
{ 
    print "defined"; 
} 

Y si nos fijamos en la documentación sobre perldoc -f defined, se dice que esta forma de comprobación está en desuso.

Use of "defined" on aggregates (hashes and arrays) is deprecated. 
2

si usted ve la documentación de defined, se encuentra que,

When defined used on a hash element, 
it tells you whether the value is defined, 
not whether the key exists in the hash. 

tratar sencilla, if (%a_hash) { print "has hash members\n" }

Nota: undef es el valor de una variable que nunca se ha inicializado (o que se ha restablecido utilizando la función undef). The defined function returns true if the value of the expression is not undef.

Cuestiones relacionadas