Quelle est la signification de @_ en Perl?


Réponses:


118

perldoc perlvar est le premier endroit pour vérifier toute information de variable Perl nommée spéciale.

Citant:

@_: Dans un sous-programme, le tableau @_contient les paramètres passés à ce sous-programme.

Plus de détails peuvent être trouvés dans perldoc perlsub (sous-routines Perl) lié à partir de perlvar:

Tous les arguments passés apparaissent dans le tableau @_.

Par conséquent, si vous appelez une fonction avec deux arguments, ceux-ci seront stockés dans $_[0]et $_[1].

Le tableau @_est un tableau local , mais ses éléments sont des alias pour les paramètres scalaires réels . En particulier, si un élément $ _ [0] est mis à jour, l'argument correspondant est mis à jour (ou une erreur se produit s'il ne peut pas être mis à jour).

Si un argument est un tableau ou un élément de hachage qui n'existait pas lorsque la fonction a été appelée, cet élément est créé uniquement lorsque (et si) il est modifié ou qu'une référence à celui-ci est prise. (Certaines versions antérieures de Perl créaient l'élément, que l'élément soit affecté ou non.) Assigner à l'ensemble du tableau @_ supprime cet alias et ne met à jour aucun argument.


Merci, je ne me suis habitué que récemment à vérifier perldoc, et j'ai trouvé les pages Web utiles: perldoc.perl.org/perlvar.html Ce n'était pas mal de créer un stub perl qui lance cela sur le Web ... le formatage d'une page Web m'aide beaucoup.
aschultz

27

Habituellement, vous développez les paramètres passés à un sous à l'aide de la @_variable:

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

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

C'est la façon dont on prétend être correcte par perlcritic .


2
c'est une fois avec laquelle je ne suis pas d'accord perlcritic, personnellement je pense que c'est mieux pour une fonction, mais pour une méthode, c'est utile pour shiftl'auto-référence, puis décompresser le @_tableau. Cela montre clairement qu'il s'agit d'une méthode ET que la méthode prend certains paramètres
Joel Berger

J'aurais probablement dû utiliser / connaître PERLCritic avant, mais je ne l'ai pas fait. Merci de l'utiliser dans cet exemple. Parfois, des choses que vous référencez spontanément peuvent aider quelqu'un à apprendre quelque chose d'entièrement nouveau pour lui.
aschultz

10

Le premier résultat d'une recherche pourperl @_ dit ceci :

@_ est la liste des paramètres entrants vers un sous-marin.

Il a également une explication plus longue et plus détaillée de la même chose.


3
En fait, le premier résultat de votre recherche Google renvoie désormais à cette même page.
Gabriel Southern

... sept ans plus tard, une éternité dans le temps d'Internet. C'est pourquoi j'ai à la fois lié au premier résultat et indiqué la partie pertinente: ne dépendre que de Google serait très naïf.
Piskvor a quitté le bâtiment

1
C'est vrai que c'est plusieurs années plus tard, mais c'est toujours ennuyeux de lire la réponse qui implique que vous devriez Google pour une réponse à la question. C'est une information inutile pour quelqu'un qui lit la réponse à la suite de Google.
Gabriel Southern

Je ne suis pas d'accord. "Recherchez votre problème avant de poser une question" est toujours l'étape 0. stackoverflow.com/help/how-to-ask Peut-être ennuyeux pour vous - mais il en est de même pour un tas de questions répétées auxquelles on aurait pu répondre en interrogeant d'abord les machines .
Piskvor a quitté le bâtiment

2
Oui, la recherche est la bonne première étape, mais il n'est pas nécessaire d'inclure des instructions pour rechercher dans votre réponse. Ce sont des informations redondantes qui n'ajoutent aucune valeur, et c'est ironique parce que si quelqu'un suit le lien de recherche dans votre réponse, cela les ramène là où ils ont commencé.
Gabriel Southern

10

La question était de savoir ce que @_ signifie en Perl. La réponse à cette question est que, dans la mesure où cela$_ signifie en Perl, cela signifie de la même manière qu'ils .@_

Personne ne semble avoir mentionné cet aspect critique de sa signification - ainsi que le leur .

Ils sont donc tous deux utilisés comme pronoms, ou parfois comme topiques.

Ils ont généralement des antécédents nominaux, mais pas toujours.


7

Vous pouvez également utiliser shift pour des variables individuelles dans la plupart des cas:

$var1 = shift;

C'est un sujet dans lequel vous devriez approfondir vos recherches car Perl a un certain nombre de façons intéressantes d'accéder à des informations extérieures à l'intérieur de votre sous-routine.


3
Cool, celui qui m'a donné un vote défavorable simplement pour avoir affiché une autre façon de faire une chose similaire. Je me rends compte que je n'ai pas répondu directement à la question parce que quelqu'un l'a déjà fait, mais j'ai proposé une forme alternative qui déroute souvent les nouveaux programmeurs Perl.
hockfan86

5

Toutes les "variables spéciales" de Perl sont répertoriées dans la page de documentation de perlvar .


2

Aussi si une fonction renvoie un tableau, mais que la fonction est appelée sans affecter ses données retournées à une variable comme ci-dessous. Ici, split () est appelé, mais il n'est affecté à aucune variable. Nous pouvons accéder à ses données renvoyées plus tard via @_:

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

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

Cela divisera la chaîne $stret définira le tableau @_.


1

@ est utilisé pour un tableau.

Dans un sous-programme ou lorsque vous appelez une fonction en Perl, vous pouvez passer la liste des paramètres. Dans ce cas, @_is peut être utilisé pour passer la liste de paramètres à la fonction:

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";
}

Appel de fonction

Average(10, 20, 30);

Si vous observez le code ci-dessus, voyez la foreach $item(@_)ligne ... Ici, il passe le paramètre d'entrée.


Tu devrais toujours use strict. J'ai donc édité votre sous-fonction.
EverythingRightPlace

0

N'essayez jamais de modifier la variable @_ !!!! Ils ne doivent pas être touchés. Ou vous obtenez un effet insoupçonné. Par exemple...

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

Avant d'appeler sub1 $ size contiennent 1234. Mais après 500 (!!) Donc vous n'éditez pas cette valeur !!! Vous pouvez passer deux valeurs ou plus et les modifier dans le sous-programme et elles seront toutes modifiées! Je n'ai jamais vu cet effet décrit. Les programmes que j'ai vus quittent également @_ array en lecture seule. Et seulement que vous pouvez passer en toute sécurité la variable ne change pas le sous-programme interne Vous devez toujours faire cela:

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

assignez @_ aux variables de procédure de sous-programme local et travaillez ensuite avec elles. Également dans certains algorithmes récursifs profonds qui relancent le tableau, vous pouvez utiliser cette approche pour réduire la mémoire utilisée pour les variables locales. Seulement si retournez @_ array le même.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.