Qual é o significado de @_ em Perl?


Respostas:


118

perldoc perlvar é o primeiro lugar para verificar qualquer informação de variável Perl com nome especial.

Citando:

@_: Dentro de uma sub-rotina, a matriz @_contém os parâmetros passados ​​para essa sub-rotina.

Mais detalhes podem ser encontrados em perldoc perlsub (sub-rotinas Perl) vinculadas ao perlvar:

Quaisquer argumentos passados ​​aparecem na matriz @_.

Portanto, se você chamar uma função com dois argumentos, eles serão armazenados em $_[0]e $_[1].

A matriz @_é uma matriz local , mas seus elementos são apelidos para os parâmetros escalares reais . Em particular, se um elemento $ _ [0] for atualizado, o argumento correspondente será atualizado (ou ocorrerá um erro se não for atualizável).

Se um argumento for uma matriz ou elemento hash que não existia quando a função foi chamada, esse elemento será criado somente quando (e se) for modificado ou uma referência a ele for feita. (Algumas versões anteriores do Perl criavam o elemento independentemente de o elemento ter sido atribuído ou não.) Atribuir a todo o array @_ remove aquele apelido e não atualiza nenhum argumento.


Obrigado, recentemente me acostumei a verificar o perldoc e achei as páginas da web úteis: perldoc.perl.org/perlvar.html Não foi ruim fazer um stub de perl que o inicia na web ... a formatação de uma página da web me ajuda muito.
aschultz

27

Normalmente, você expande os parâmetros passados ​​para um sub usando a @_variável:

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

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

Essa é a maneira que o perlcrítico afirma ser correta .


2
esta é uma das vezes da qual discordo perlcritic, pessoalmente acho que isso é melhor para uma função, mas para um método, é útil para shifta auto-referência, depois descompacte o @_array. Isso deixa claro que este é um método E que o método leva certos parâmetros
Joel Berger

Eu provavelmente deveria ter usado / conhecido sobre PERLCritic antes, mas não o fiz. Obrigado por usá-lo neste exemplo. Às vezes, coisas que você consulta de improviso podem ajudar alguém a aprender algo totalmente novo para essa pessoa.
aschultz

10

O primeiro resultado de uma pesquisa porperl @_ diz o seguinte :

@_ é a lista de parâmetros de entrada para um sub.

Ele também tem uma explicação mais longa e detalhada do mesmo.


3
Na verdade, o primeiro resultado de sua pesquisa no Google agora leva a esta página.
Gabriel Southern

... sete anos depois, uma eternidade no tempo da Internet. Por isso vinculei ao primeiro resultado e citei a parte relevante: depender apenas do Google seria muito ingênuo.
Piskvor saiu do prédio de

1
verdade, muitos anos depois, mas ainda é irritante ler a resposta que sugere que você deve pesquisar no Google para obter uma resposta à pergunta. É uma informação inútil para alguém que lê a resposta como resultado de uma busca no Google.
Gabriel Southern

Discordo. "Pesquise o seu problema antes de fazer uma pergunta" ainda é a etapa 0. stackoverflow.com/help/how-to-ask Irritante para você , talvez - mas também é um monte de perguntas repetidas que poderiam ter sido respondidas consultando as máquinas primeiro .
Piskvor saiu do prédio de

2
Sim, pesquisar é o primeiro passo correto, mas não é necessário incluir instruções para pesquisar em sua resposta. São informações redundantes que não agregam valor e são irônicas porque, se alguém seguir o link de pesquisa em sua resposta, isso o levará de volta ao ponto de partida.
Gabriel Southern

10

A questão era o que @_ significa em Perl. A resposta a essa pergunta é que, na medida em que $_significa isso em Perl, da @_mesma forma significa eles .

Ninguém parece ter mencionado esse aspecto crítico de seu significado - tão bem quanto o deles .

Conseqüentemente, eles são usados ​​como pronomes ou, às vezes, como tópicos.

Eles geralmente têm antecedentes nominais, embora nem sempre.


7

Você também pode usar shift para variáveis ​​individuais na maioria dos casos:

$var1 = shift;

Este é um tópico no qual você deve pesquisar mais, pois o Perl tem várias maneiras interessantes de acessar informações externas dentro de sua rotina secundária.


3
Legal, quem me deu um voto negativo simplesmente por postar outra maneira de fazer algo semelhante. Percebo que não respondi a pergunta diretamente porque alguém já respondeu, mas ofereci uma forma alternativa com a qual os novos programadores de perl costumam ser confundidos.
hockfan86

5

Todas as "variáveis ​​especiais" do Perl estão listadas na página de documentação do perlvar .


2

Além disso, se uma função retorna um array, mas a função é chamada sem atribuir seus dados retornados a qualquer variável como abaixo. Aqui, split () é chamado, mas não é atribuído a nenhuma variável. Podemos acessar seus dados retornados posteriormente através de @_:

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

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

Isso irá dividir a string $stre definir o array @_.


1

@ é usado para uma matriz.

Em uma sub-rotina ou ao chamar uma função em Perl, pode-se passar a lista de parâmetros. Nesse caso, @_pode ser usado para passar a lista de parâmetros para a função:

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

Chamada de função

Average(10, 20, 30);

Se você observar o código acima, veja a foreach $item(@_)linha ... Aqui passa o parâmetro de entrada.


Você deve sempre use strict. Eu editei sua subfunção, portanto.
EverythingRightPlace

0

Nunca tente editar a variável @_ !!!! Eles não devem ser tocados. Ou você obterá algum efeito inesperado. Por exemplo...

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

Antes da chamada, o tamanho sub1 $ contém 1234. Mas depois de 500 (!!) Portanto, não edite este valor !!! Você pode passar dois ou mais valores e alterá-los na sub-rotina e todos eles serão alterados! Nunca vi esse efeito descrito. Os programas que vi também deixam @_ array somente leitura. E só que você pode passar com segurança a variável não mudou a sub-rotina interna. Você deve sempre fazer isso:

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

atribua @_ às variáveis ​​de procedimento da sub-rotina local e, em seguida, trabalhe com elas. Além disso, em alguns algoritmos recursivos profundos que returun array, você pode usar essa abordagem para reduzir a memória usada para vars locais. Somente se retornar @_ array o mesmo.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.