2008-10-27 34 views
13

estoy mirando el siguiente fragmento de código:

my @ret = <someMethod> 
return (undef) if($DB_ERROR); 
return (undef) unless ($#ret >= 0); 

¿Se $# sólo le dará un recuento de elementos en una matriz?

+1

me cambiaron a $ # $ # matriz en el título. Debes darte cuenta de que $ # en sí mismo es una variable mágica (aunque creo que se eliminó en Perl 5.10) –

+6

Además, me gustaría señalar que tienes un error potencial en tu script. No debe regresar (undef), sino simplemente decir return.En el contexto de la lista, su función se evaluará como verdadera. –

Respuesta

34

$#arrayname le da el índice del último elemento, por lo que si el array @ret tiene 2 elementos, entonces es $#ret 1.

Y, como se ha señalado por Barry Brown, una matriz vacía da -1.

para obtener la longitud puede utilizar la matriz en contexto escalar:

print scalar @ret; 
+0

Además, si @ret no tiene nada, $ # ret devolverá -1. –

5

en cuenta que los $ # expresión gama volverá -1 cuando matriz tiene elementos cero.

23

edg es correcto, pero el código original es innecesariamente obtuso. En la mayoría de los casos, $#foo es una bandera roja que el código podría escribirse más simplemente usando scalar @foo.

return (undef) unless ($#ret >= 0); 

unless foo >= bar es difícil de descifrar. Primero, conviértalo en una declaración positiva.

return (undef) if ($#ret < 0); 

¿Cuándo es $ # ret < 0? Cuando es -1. A $ # ret de -1 es una matriz de longitud 0. Así que lo anterior se puede escribir mucho más simplemente como ...

return (undef) if scalar @ret <= 0; 

Pero no se puede tener una matriz de longitud negativa, por lo ...

return (undef) if scalar @ret == 0; 

== Y es en contexto escalar, por lo que "escalar" es redundante ...

return (undef) if @ret == 0; 

Pero eso es sólo una forma prolija de decir "si @ret es falso".

return (undef) if [email protected]; 

Lo que creo que para los modificadores de enunciados simples se expresa mejor a menos.

return (undef) unless @ret; 

¿No es más fácil de seguir?

Como nota final, return undef se desaconseja porque hace algo incorrecto en el contexto de la lista. Obtiene una lista que contiene un elemento undef, que es verdadero. En su lugar, solo use un retorno en blanco que devuelve undef en contexto escalar y una lista vacía en contexto de lista.

return unless @ret; 
+1

Y un lugar donde $ # foo no es una bandera roja estaría en una porción de matriz ... mi @five_to_end = @foo [5 .. $ # foo]; – draegtun

+0

Mighty fine simplification! –

+0

Re: 'return undef' siendo desalentado. En algunos casos, desea devolver un 'undef' explícito incluso en el contexto de la lista. Depende de cómo se usa la función generalmente. No es que no deberías usar 'return undef', es solo que no deberías usarlo sin pensar" ¿por qué estoy usando 'return undef' aquí?" Si tienes una buena respuesta, adelante y hazlo. – cjm

2

En resumen todos los demás, que el código es mucho más legible si se escribe así:

my @ret = someMethod(); 
return if $DB_ERROR; 
return unless @ret;