Qual è il significato di @_ in Perl?


Risposte:


118

perldoc perlvar è il primo posto in cui verificare la presenza di informazioni sulle variabili Perl con nomi speciali.

Citando:

@_: All'interno di una subroutine l'array @_contiene i parametri passati a quella subroutine.

Maggiori dettagli possono essere trovati in perldoc perlsub (subroutine Perl) collegati da perlvar:

Tutti gli argomenti passati vengono visualizzati nell'array @_.

Pertanto, se si chiama una funzione con due argomenti, questi verranno memorizzati in $_[0]e $_[1].

L'array @_è un array locale , ma i suoi elementi sono alias per i parametri scalari effettivi . In particolare, se un elemento $ _ [0] viene aggiornato, viene aggiornato l'argomento corrispondente (o si verifica un errore se non è aggiornabile).

Se un argomento è un array o un elemento hash che non esisteva quando la funzione è stata chiamata, quell'elemento viene creato solo quando (e se) viene modificato o viene preso un riferimento ad esso. (Alcune versioni precedenti di Perl creavano l'elemento indipendentemente dal fatto che l'elemento fosse assegnato o meno.) Assegnare all'intero array @_ rimuove l'aliasing e non aggiorna alcun argomento.


Grazie, solo di recente mi sono abituato a controllare perldoc, e ho trovato utili le pagine web: perldoc.perl.org/perlvar.html Non è stato male creare uno stub perl che lo lanci sul web ... la formattazione di una pagina web mi aiuta molto.
aschultz

27

Di solito, espandi i parametri passati a un sub utilizzando la @_variabile:

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

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

Questo è il modo affermato di essere corretto da Perlcritic .


2
questa è una volta in cui non sono d'accordo perlcritic, personalmente penso che questo sia il migliore per una funzione, ma per un metodo, è utile per shiftl'auto referenza, quindi decomprimere l' @_array. Ciò rende chiaro che questo è un metodo E che il metodo accetta determinati parametri
Joel Berger

Probabilmente avrei dovuto usare / conoscere PERLCritic prima, ma non l'ho fatto. Grazie per averlo utilizzato in questo esempio. A volte le cose a cui fai riferimento improvvisamente possono aiutare qualcuno a imparare qualcosa di completamente nuovo per lui.
aschultz

10

Il primo colpo di una ricercaperl @_ dice questo :

@_ è l'elenco dei parametri in arrivo a un sub.

Ha anche una spiegazione più lunga e dettagliata dello stesso.


3
In realtà il primo risultato della tua ricerca su Google ora si collega a questa stessa pagina.
Gabriel Southern

... sette anni dopo, un'eternità nel tempo di Internet. Ecco perché mi sono collegato al primo risultato e ho chiesto la parte rilevante: dipendere da Google da solo sarebbe molto ingenuo.
Piskvor ha lasciato l'edificio il

1
è vero che sono passati molti anni, ma è ancora fastidioso leggere la risposta che implica che dovresti cercare una risposta alla domanda su Google. È un'informazione inutile per qualcuno che legge la risposta come risultato di Google.
Gabriel Southern

Non sono d'accordo. "Cerca per il vostro problema prima di porre una domanda" è ancora un passo 0. stackoverflow.com/help/how-to-ask fastidioso per voi , forse - ma così è un mucchio di domande ripetute che potrebbe essere stato risposto interrogando le macchine prima .
Piskvor ha lasciato l'edificio il

2
Sì, la ricerca è il primo passo corretto, ma non è necessario includere istruzioni per la ricerca nella risposta. Sono informazioni ridondanti che non aggiungono valore ed è ironico perché se qualcuno segue il link di ricerca nella tua risposta, lo riporta al punto di partenza.
Gabriel Southern

10

La domanda era cosa @_ significa in Perl. La risposta a questa domanda è che, nella misura in cui $_i mezzi che in Perl, @_similmente significa che .

Nessuno sembra aver menzionato questo aspetto critico del suo significato, così come il loro .

Di conseguenza sono entrambi usati come pronomi, o talvolta come topicalizzatori.

In genere hanno antecedenti nominali, sebbene non sempre.


7

È inoltre possibile utilizzare shift per singole variabili nella maggior parte dei casi:

$var1 = shift;

Questo è un argomento in cui dovresti approfondire la ricerca poiché Perl ha una serie di modi interessanti per accedere a informazioni esterne all'interno della tua sub routine.


3
Fantastico, chiunque mi abbia dato un voto negativo semplicemente per aver pubblicato un altro modo per fare una cosa simile. Mi rendo conto di non aver risposto direttamente alla domanda perché qualcuno lo aveva già fatto, ma ho offerto una forma alternativa dalla quale i nuovi programmatori perl sono spesso confusi.
hockfan86

5

Tutte le "variabili speciali" di Perl sono elencate nella pagina della documentazione di perlvar .


2

Anche se una funzione restituisce un array, ma la funzione viene chiamata senza assegnare i dati restituiti a nessuna variabile come di seguito. Qui viene chiamata split (), ma non è assegnata a nessuna variabile. Possiamo accedere ai dati restituiti in seguito tramite @_:

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

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

Questo dividerà la stringa $stre imposterà l'array @_.


1

@ viene utilizzato per un array.

In una subroutine o quando chiamate una funzione in Perl, potete passare l'elenco dei parametri. In tal caso, @_è possibile utilizzare per passare l'elenco dei parametri alla funzione:

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

Chiamata di funzione

Average(10, 20, 30);

Se osservi il codice sopra, vedi la foreach $item(@_)riga ... Qui passa il parametro di input.


Dovresti sempre use strict. Ho quindi modificato la tua funzione secondaria.
EverythingRightPlace

0

Non provare mai a modificare la variabile @_ !!!! Non devono essere toccati .. Oppure si ottiene qualche effetto insospettato. Per esempio...

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

Prima di chiamare sub1 $ size contiene 1234. Ma dopo 500 (!!) Quindi non modificare questo valore !!! Puoi passare due o più valori e modificarli nella subroutine e tutti verranno modificati! Non ho mai visto questo effetto descritto. Anche i programmi che ho visto lasciano l'array @_ in sola lettura. E solo che puoi passare in sicurezza la variabile, non cambiare la subroutine interna Devi sempre farlo:

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

assegna @_ alle variabili di procedura della subroutine locale e poi lavora con esse. Anche in alcuni algoritmi ricorsivi profondi che rieseguono un array è possibile utilizzare questo approccio per ridurre la memoria utilizzata per le variabili locali. Solo se restituisce lo stesso array @_.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.