2012-03-21 14 views
11

dicen que una subrutina Perl devuelve una matriz:¿Cómo puedo acceder selectivamente a elementos devueltos por una subrutina de Perl?

sub arrayoutput 
{ 
    ...some code... 
    return @somearray; 
} 

Quiero tener acceso a un elemento de la matriz única específica de esto, digo el primero. Entonces podría hacer:

@temparray=arrayoutput(argument); 

y luego consultar $temparray[0].

Pero este tipo de referencia corta no funciona: $arrayoutput(some argument)[0].

Estoy acostumbrado a Python y nuevo en Perl, así que sigo buscando una forma corta, intuitiva, similar a la de pitón (a=arrayoutput(some argument)[0]) para obtener este valor. Mis programas de Perl se están volviendo muy largos y el uso de arreglos temporales como ese parece feo. ¿Hay alguna manera en Perl para hacer esto?

Respuesta

10

Slices

use warnings; 
use strict; 

sub foo { 
    return 'a' .. 'z' 
} 

my $y = (foo())[3]; 
print "$y\n"; 

__END__ 

d 

ACTUALIZACIÓN: Otro ejemplo de código para hacer frente a su comentario. No es necesario una variable intermedia:

use warnings; 
use strict; 

sub foo { 
    return 'a' .. 'z' 
} 

print((foo())[7], "\n"); 

if ((foo())[7] eq 'h') { 
    print "I got an h\n"; 
} 

__END__ 

h 
I got an h 
+0

+1, esto funciona. Pero nuevamente necesito crear una variable intermedia para acceder al valor. Pero este es un paso mejor, ya que al menos puedo usarlo cuando de todos modos necesito una asignación variable. Pero no en otros escenarios, digamos una instrucción 'print (foo()) [3]' o una instrucción 'if ((foo()) [3] ...)'. –

+0

Puedes hacer ambas cosas. Ver mi respuesta actualizada. – toolic

+2

Tenga en cuenta que 'print (foo()) [7]' no funcionará como se esperaba, ya que perl supone que los paréntesis pertenecen a la llamada de función, y así lo analiza como equivalente a '(print foo()) [7] '. O bien 'print ((foo()) [7])' o, más idiomáticamente, 'print + (foo()) [7]' funcionarán. –

2

Una forma podría ser [(arrayoutput(some argument))]->[0].

+0

+1, esto funciona! No entiendo por qué esto está siendo degradado. ¿Hay alguna mala práctica de programación o algo más sucediendo aquí que me estoy perdiendo? –

+1

No es necesario utilizar una matriz de referencia. Supongo que esa es la razón del voto en baja. –

14

Tire fuera el primer argumento sólo a través contexto de la lista:

my ($wanted) = array_returning_sub(@args); 

TIMTOWTDI con una rodaja:

my $wanted = (array_returning_sub(@args))[0]; 

Ambos estilos podrían extenderse para extraer el n-ésimo elemento de la matriz devuelta, aunque el sector de la lista es un poco más simple:

my (undef, undef, $wanted, undef, $needed) = array_returning_sub(@args); 

my ($wanted, $needed) = (array_returning_sub(@args))[2,4]; 
+0

Leído como '" array-returning sub "', not '" array que devuelve [a] sub "' – Zaid

+1

Excepto que los subs no pueden devolver matrices. Solo pueden devolver listas de escalares. – ikegami

+0

+1. ¡Entonces solo era una cuestión de paréntesis! El segmento de lista también es mejor que el contexto de lista para listas largas. –

Cuestiones relacionadas