Pergunta

O que é a diferença entre os contextos escalares e lista em Perl e é que isto tem qualquer paralelo em outras linguagens como Java ou Javascript?

Foi útil?

Solução

Vários operadores em Perl são sensíveis ao contexto e produzir resultados diferentes na lista e contexto escalar.

Por exemplo:

my(@array) = (1, 2, 4, 8, 16);
my($first) = @array;
my(@copy1) = @array;
my @copy2  = @array;
my $count  = @array;

print "array: @array\n";
print "first: $first\n";
print "copy1: @copy1\n";
print "copy2: @copy2\n";
print "count: $count\n";

Output:

array: 1 2 4 8 16
first: 1
copy1: 1 2 4 8 16
copy2: 1 2 4 8 16
count: 5

Agora:

  • $first contém um (o primeiro elemento da matriz), porque os parênteses na my($first) proporcionar um contexto matriz, mas só há espaço para um valor em $first.
  • tanto @copy1 e @copy2 conter uma cópia do @array,
  • e $count contém 5 porque é um contexto escalar, e avalia @array para o número de elementos na matriz em um contexto escalar.

Exemplos mais elaborados poderiam ser construídos também (os resultados são um exercício para o leitor):

my($item1, $item2, @rest) = @array;
my(@copy3, @copy4) = @array, @array;

Não há paralelo direto à lista e contexto escalar em outros idiomas que eu conheço.

Outras dicas

contexto escalar é o que você começa quando você está procurando um único valor. contexto de lista é o que você começa quando você está procurando vários valores. Um dos lugares mais comuns para ver a distinção é quando se trabalha com matrizes:

@x = @array;  # copy an array
$x = @array;  # get the number of elements in an array

Outros operadores e funções são sensíveis ao contexto, bem como:

$x   = 'abc' =~ /(\w+)/;  # $x = 1
($x) = 'abc' =~ /(\w+)/;  # $x = 'abc'
@x   = localtime();       # (seconds, minutes, hours...)
$x   = localtime();       # 'Thu Dec 18 10:02:17 2008'

Como um operador (ou função) se comporta em um determinado contexto cabe ao operador. Não existem regras gerais de como as coisas devem se comportar.

Você pode fazer seu próprio contexto sub-rotinas sensíveis usando a função wantarray para determinar o contexto de chamada. Você pode forçar uma expressão a ser avaliada no contexto escalar usando a palavra-chave scalar.

Além de escalar e lista contextos você também vai ver "vazio" (sem valor de retorno esperado) e "boolean" (um verdadeiro / falso valor esperado) contextos mencionados na documentação.

Isto significa simplesmente que um tipo de dados serão avaliados com base no modo de operação. Por exemplo, uma atribuição para um meio escalares do lado direito será avaliada como um escalar.

Eu acho que o melhor meio de contexto entendimento está aprendendo sobre wantarray. Então, imagine que = é uma sub-rotina que implementos wantarray:

sub = {
  return if ( ! defined wantarray ); # void: just return (doesn't make sense for =)
  return @_ if ( wantarray ); # list: return the array
  return $#_ + 1; # scalar: return the count of the @_
}

Os exemplos este post trabalho como se a rotina acima é chamado, passando do lado direito do como parâmetro.

Quanto aos paralelos em outros idiomas, sim, eu ainda sustentam que suportes de linguagem algo praticamente todos os similar. Polimorfismo é semelhante em todas as linguagens OO. Outro exemplo, Java converte objetos para String em certos contextos. E cada linguagem de script sem tipo que usei tem conceitos similares.

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