¿Cuál es el significado de @_ en Perl?

Respuestas:

119

perldoc perlvar es el primer lugar para verificar cualquier información de variable Perl con nombre especial.

Citando:

@_: Dentro de una subrutina, la matriz @_contiene los parámetros pasados ​​a esa subrutina.

Se pueden encontrar más detalles en perldoc perlsub (subrutinas de Perl) enlazadas desde perlvar:

Todos los argumentos pasados ​​aparecen en la matriz @_.

Por lo tanto, si llama a una función con dos argumentos, estos se almacenarán en $_[0]y $_[1].

La matriz @_es una matriz local , pero sus elementos son alias de los parámetros escalares reales . En particular, si se actualiza un elemento $ _ [0], se actualiza el argumento correspondiente (o se produce un error si no es actualizable).

Si un argumento es una matriz o un elemento hash que no existía cuando se llamó a la función, ese elemento se crea solo cuando (y si) se modifica o se toma una referencia a él. (Algunas versiones anteriores de Perl creaban el elemento independientemente de si el elemento estaba asignado o no). La asignación a toda la matriz @_ elimina ese alias y no actualiza ningún argumento.

DVK
fuente
Gracias, solo recientemente me he acostumbrado a revisar perldoc, y las páginas web me han resultado útiles: perldoc.perl.org/perlvar.html No estuvo mal hacer un código auxiliar de perl que lance esto en la web ... el formato de una página web me ayuda mucho.
aschultz
27

Por lo general, expande los parámetros pasados ​​a un sub usando la @_variable:

sub test{
  my ($a, $b, $c) = @_;
  ...
}

# call the test sub with the parameters
test('alice', 'bob', 'charlie');

Esa es la forma que afirma Perlcritic como correcta .

eckes
fuente
2
esta es una vez con la que no estoy de acuerdo perlcritic, personalmente creo que esto es mejor para una función, pero para un método, es útil para shiftla autorreferencia, luego descomprime la @_matriz. Esto deja en claro que este es un método Y que el método toma ciertos parámetros
Joel Berger
Probablemente debería haber usado / sabido acerca de PERLCritic antes, pero no lo hice. Gracias por usarlo en este ejemplo. A veces, las cosas a las que hace referencia de manera espontánea pueden ayudar a alguien a aprender algo completamente nuevo para ellos.
aschultz
12

El primer resultado de una búsquedaperl @_ dice esto :

@_ es la lista de parámetros entrantes a un sub.

También tiene una explicación más larga y detallada del mismo.

Piskvor salió del edificio
fuente
3
En realidad, el primer resultado de su búsqueda de Google ahora enlaza a esta misma página.
Gabriel Southern
... siete años después, una eternidad en el tiempo de Internet. Por eso, me vinculé al primer resultado y pregunté la parte relevante: depender solo de Google sería muy ingenuo.
Piskvor salió del edificio el
1
Es cierto que han pasado muchos años, pero sigue siendo molesto leer la respuesta que implica que debería buscar en Google una respuesta a la pregunta. Es información inútil para alguien que lee la respuesta como resultado de buscar en Google.
Gabriel Southern
2
Sí, la búsqueda es el primer paso correcto, pero no es necesario incluir instrucciones para buscar en su respuesta. Es información redundante que no agrega valor, y es irónico porque si alguien sigue el enlace de búsqueda en su respuesta, lo devuelve al punto de partida.
Gabriel Southern
1
todas estas respuestas de "google it" han envejecido tan mal 😂
Austin Adams
11

La pregunta era qué @_ significa en Perl. La respuesta a esa pregunta es que, en la medida en $_medios que en Perl, @_significa igualmente que .

Nadie parece haber mencionado este aspecto crítico de su significado, así como el de ellos .

En consecuencia, ambos se usan como pronombres o, a veces, como topicalizadores.

Suelen tener antecedentes nominales, aunque no siempre.

tchrist
fuente
7

También puede usar shift para variables individuales en la mayoría de los casos:

$var1 = shift;

Este es un tema en el que debería investigar más, ya que Perl tiene varias formas interesantes de acceder a información externa dentro de su subrutina.

hockfan86
fuente
3
Genial, quienquiera que me haya votado en contra simplemente por publicar otra forma de hacer algo similar. Me doy cuenta de que no respondí la pregunta directamente porque alguien ya lo hizo, pero ofrecí una forma alternativa que a menudo confunde a los nuevos programadores de Perl.
hockfan86
5

Todas las "variables especiales" de Perl se enumeran en la página de documentación de perlvar .

aschepler
fuente
2

Además, si una función devuelve una matriz, pero la función se llama sin asignar sus datos devueltos a ninguna variable como a continuación. Aquí se llama split (), pero no se asigna a ninguna variable. Podemos acceder a sus datos devueltos más tarde a través de @_:

$str = "Mr.Bond|Chewbaaka|Spider-Man";
split(/\|/, $str);

print @_[0]; # 'Mr.Bond'

Esto dividirá la cadena $stry establecerá la matriz @_.

Afser2000
fuente
1

@ se utiliza para una matriz.

En una subrutina o cuando llama a una función en Perl, puede pasar la lista de parámetros. En ese caso, @_se puede usar para pasar la lista de parámetros a la función:

sub Average{

    # Get total number of arguments passed.
    $n = scalar(@_);
    $sum = 0;

    foreach $item (@_){

        # foreach is like for loop... It will access every
        # array element by an iterator
        $sum += $item;
    }

    $average = $sum / $n;

    print "Average for the given numbers: $average\n";
}

Llamada de función

Average(10, 20, 30);

Si observa el código anterior, vea la foreach $item(@_)línea ... Aquí pasa el parámetro de entrada.

Omar Faroque Anik
fuente
Siempre deberías use strict. Por lo tanto, edité su función secundaria.
EverythingRightPlace
0

¡Nunca intente editar a la variable @_! No deben tocarse ... O obtendrás algún efecto insospechado. Por ejemplo...

my $size=1234;
sub sub1{
  $_[0]=500;
}
sub1 $size;

Antes de llamar a sub1 $, el tamaño contiene 1234. Pero después de 500 (!!) ¡¡¡Así que no edite este valor !!! Puede pasar dos o más valores y cambiarlos en una subrutina y ¡todos se cambiarán! Nunca he visto este efecto descrito. Los programas que he visto también dejan @_ array readonly. Y solo que puede pasar de manera segura la variable no cambia la subrutina interna Siempre debe hacer eso:

sub sub2{
  my @m=@_;
  ....
}

asigne @_ a las variables de procedimiento de subrutina local y luego trabajó con ellas. También en algunos algoritmos recursivos profundos que devuelven una matriz, puede usar este enfoque para reducir la memoria utilizada para las variables locales. Solo si devuelve @_ array igual.

Anatoly
fuente