Pergunta

Desde arrays e hashes só pode conter escalares em Perl, por que você tem que usar o $ para dizer o intérprete que o valor é um escalar ao acessar matriz ou de hash elementos? Em outras palavras, supondo que você tem um @myarray array e um %myhash de hash, por que você precisa fazer:

$x = $myarray[1];
$y = $myhash{'foo'};

em vez de apenas fazer:

$x = myarray[1];
$y = myhash{'foo'};

Por que o acima ambígua?

Não seria código ilegal Perl se era tudo menos um $ naquele lugar? Por exemplo, não são todos os seguintes ilegal em Perl?

@var[0];
@var{'key'};
%var[0];
%var{'key'};
Foi útil?

Solução

As fatias não são ilegais:

@slice = @myarray[1, 2, 5];
@slice = @myhash{qw/foo bar baz/};

E eu suspeito que é parte da razão por que você precisa para especificar se você deseja obter um valor único para fora do hash / array ou não.

Outras dicas

Eu apenas usei

my $x = myarray[1];

em um programa e, para minha surpresa, aqui está o que aconteceu quando eu corri-lo:

$ perl foo.pl 
Flying Butt Monkeys!

Isso porque o programa completo fica assim:

$ cat foo.pl 
#!/usr/bin/env perl

use strict;
use warnings;

sub myarray {
  print "Flying Butt Monkeys!\n";
}

my $x = myarray[1];

chamadas Então MyArray uma sub-rotina de passá-lo uma referência para um array anônimo contendo um único elemento, 1.

Essa é outra razão que você precisa o sigilo em um acesso de matriz.

O sigilo dar-lhe o tipo de retorno do recipiente. Então, se algo começa com @, você sabe que ele retorna uma lista. Se ele começa com $, ele retorna um escalar.

Agora, se houver apenas um identificador após o sigilo (como $foo ou @foo, então é um simples acesso variável. Se ele é seguido por um [, é um acesso em uma matriz, se for seguido por um {, é uma acesso em um hash.

# variables
$foo
@foo

# accesses
$stuff{blubb} # accesses %stuff, returns a scalar
@stuff{@list} # accesses %stuff, returns an array
$stuff[blubb] # accesses @stuff, returns a scalar
              # (and calls the blubb() function)
@stuff[blubb] # accesses @stuff, returns an array

Alguns idiomas humanos têm conceitos muito semelhantes.

No entanto, muitos programadores descobriram que confuso, então Perl 6 usa um sigilo invariante.

Em geral, o compilador Perl 5 quer saber em tempo de compilação, se algo está na lista ou no contexto escalar, assim, sem o líder sigilo alguns termos se tornaria ambígua.

Isso é válido Perl: @var[0]. É uma faixa da matriz de um comprimento. @var[0,1] seria uma fatia de matriz de comprimento de dois.

Não

@var['key'] é válido Perl porque as matrizes só podem ser indexados por números, e os outros dois (%var[0] and %var['key']) não são válidos Perl porque fatias de hash usar o} {para indexar o hash.

@var{'key'} e @var{0} são ambos fatias de hash válido, no entanto. Obviamente que não é normal para tomar fatias de um comprimento, mas é certamente válido.

seção fatia de perldata perldoc para obter mais informações sobre o corte em Perl.

As pessoas já têm apontado que você pode ter fatias e contextos, mas sigilos estão lá para separar as coisas que são variáveis ??de tudo o resto. Você não tem que saber todas as palavras-chave ou nomes de sub-rotina de escolher um nome de variável sensível. É uma das grandes coisas que eu perca sobre Perl em outros idiomas.

Não consigo pensar em uma maneira que

$x = myarray[1];

é ambígua - o que se você queria um array chamado m

$x = m[1];

Como você pode dizer que para além de um jogo de regex?

Em outras palavras, a sintaxe é lá para ajudar o intérprete Perl, assim, interpretar!

Em Perl 5 (a ser mudado em Perl 6) um sigilo indica o contexto de sua expressão.

  • Você quer um fora escalar particular de um hash por isso é $hash{key}.
  • Você quer que o valor de um determinado slot de um array, por isso é $array[0].

No entanto, como fora apontado por Zigdon, fatias são legais. Eles interpretam os aquelas expressões em um lista contexto.

  • Você quer uma lista de 1 valor em um hash de obras @hash{key}
  • Mas as listas também maiores funcionar tão bem, como @hash{qw<key1 key2 ... key_n>}.

  • Você quer um par de slots de fora funciona um conjunto @array[0,3,5..7,$n..$n+5]

  • @array[0] é uma lista de tamanho 1.

Não existe um "contexto de hash", então, nem %hash{@keys} nem %hash{key} tem significado.

Então você tem "@" + "array[0]" <=> + como a expressão completa.

O sigilo fornece o contexto para o acesso:

  • $ significa contexto escalar (um escalar variável ou um único elemento de um hash ou uma matriz)
  • @ significa contexto de lista (a matriz inteira ou uma fatia de um hash ou uma matriz)
  • % é um hash inteira

Em Perl 5 você precisa dos sigilos ($ e @) porque a interpretação padrão do identificador bareword é o de uma chamada de subrotina (eliminando assim a necessidade de uso e na maioria dos casos).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top