2012-05-23 10 views
22

Duplicar posibles: How do pass one array and one string as arguments to a function?array Pass y escalar a una subrutina Perl

Tengo una función o subrutina, que se lleva en el primer parámetro como una matriz y el segundo parámetro como un escalar Por ejemplo,

sub calc { 
    my @array = $_[0]; 
    my $scalar = $_[1]; 
    print @array, $scalar; 
} 

El problema es que la función es hacer la matriz igual al primer valor de la matriz pasada en, y el escalar que es el segundo valor de la matriz ha pasado. Cuando quiero la primera array para ser la matriz completa, no necesito hacer una copia profunda de la matriz. Por ejemplo,

my @array = ('51', 'M'); 
my $scalar = 21; 

y

calc(@array, $scalar) 

imprimirá 51 M cuando quiero 51 M 21.

Respuesta

42

lo necesario para pasar en como referencia:

calc(\@array, $scalar)

Y luego acceder a ella como: my @array = @{$_[0]};

+3

Tenga en cuenta que la segunda parte de mi respuesta hará una copia de la matriz. También puede dejarlo como referencia y acceder a él de manera apropiada a través de su función – happydave

+0

Esto en realidad no funciona, lo intenté. ¿Has probado esto? –

+0

Lo siento, supongo que @ se aplica antes que [0]. Puse una versión fija con llaves alrededor de $ _ [0]. – happydave

2

La lista de argumentos en una subrutina Perl es simplemente una matriz plana. Si desea pasar una matriz distinta, debe pasarla como una matriz de referencia.

8

Puede pasar una referencia a la matriz a su función:

calc(\@array, $scalar); 

Cuando necesite acceder a elementos de @array en su subrutina, puede hacerlo así:

my $array = $_[0]; 

# access first element of array 
print $array->[0]; 

Editar: Dado que esto es una referencia a la matriz original, cualquier cambio realizado en la subrutina se reflejará en la matriz original.

+2

Genial, sabía que era un problema de sintaxis, ¡gracias! –

+0

@Dan, no fue un error de sintaxis. El problema es que no entendiste que la lista de argumentos de una subllamada se evalúa como una expresión, no como una serie de expresiones separadas por comas. – ikegami

+1

Bueno, pensé mucho, así que diría que no estoy de acuerdo. Simplemente no sabía cómo decirle a Perl que estoy pasando por una matriz. –

9

pasar su matriz a la subrutina Calc como una matriz ref:

calc(\@array, $scalar); 

Luego, en la subrutina calc, inicializar sus parámetros de entrada como esta:

sub calc { 
    my($array_ref, $scalar) = @_; 

    foreach my $item (@$array_ref) { 
    # process each item in the array ref 
    } 
} 
12

utilizar una referencia a la array como el primer argumento, o revertir los argumentos para que el escalar sea el primero y la matriz venga después:

sub reversed_args 
{ 
    my($scalar, @array) = @_; 
    # ... 
    print @array, $scalar, "\n"; 
} 

my @array = ('51', 'M'); 
my $scalar = 21; 

reversed_args($scalar, @array); 

No intente Perlprototypes (dos artículos, uno en Stack   Overflow, uno en PerlMonks).

+0

¿Cuál es la esencia de no intentar usar prototipos? –

+0

La forma más corta es "No usar prototipos Perl"; la siguiente forma más corta es "Los prototipos de la función Perl no funcionan como esperabas y los expertos recomiendan que no intentes utilizarlos". La versión larga describe algo así como "Los prototipos de Perl son un experimento fallido que causa más dolor y consternación que ayuda útil cuando se usan, lo que lleva a problemas difíciles de diagnosticar; en este camino se encuentra la desesperación y la locura". –

Cuestiones relacionadas