Domanda

Dato che array e hash possono contenere solo scalari in Perl, perché usare $ per dire all'interprete che il valore è uno scalare quando si accede a array o hash elements? In altre parole, supponendo che tu abbia un array @myarray e un hash %myhash, perché devi farlo:

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

invece di fare semplicemente:

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

Perché i precedenti sono ambigui?

Non sarebbe illegale il codice Perl se non fosse altro che un $ in quel posto? Ad esempio, in Perl non sono tutti illegali i seguenti?

@var[0];
@var{'key'};
%var[0];
%var{'key'};
È stato utile?

Soluzione

Le fette non sono illegali:

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

E sospetto che sia parte del motivo per cui è necessario specificare se si desidera ottenere un singolo valore dall'hash / array o meno.

Altri suggerimenti

Ho appena usato

my $x = myarray[1];

in un programma e, con mia sorpresa, ecco cosa è successo quando l'ho eseguito:

$ perl foo.pl 
Flying Butt Monkeys!

Questo perché l'intero programma è simile al seguente:

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

use strict;
use warnings;

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

my $x = myarray[1];

Quindi myarray chiama una subroutine passandogli un riferimento a un array anonimo contenente un singolo elemento, 1.

Questa è un'altra ragione per cui hai bisogno del sigillo su un accesso array.

Il sigillo ti dà il tipo di ritorno del contenitore. Quindi, se qualcosa inizia con @, sai che restituisce un elenco. Se inizia con $, restituisce uno scalare.

Ora se c'è solo un identificatore dopo il sigillo (come $foo o @foo, allora è un semplice accesso variabile. Se è seguito da un [, è un accesso su un array, se è seguito da un {, è un accesso a un 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

Alcuni linguaggi umani hanno concetti molto simili.

Comunque molti programmatori lo hanno trovato confuso, quindi Perl 6 usa un sigillo invariante.

In generale il compilatore Perl 5 vuole sapere in fase di compilazione se qualcosa è nella lista o in un contesto scalare, quindi senza il sigillo iniziale alcuni termini diventerebbero ambigui.

Questo è Perl valido: @var[0]. È una porzione di array di lunghezza uno. @var[0,1] sarebbe una porzione di array di lunghezza due.

@var['key'] non è Perl valido poiché le matrici possono essere indicizzate solo da numeri e gli altri due (%var[0] and %var['key']) non sono validi Perl perché le sezioni hash usano {} per indicizzare l'hash.

@var{'key'} e @var{0} sono entrambi sezioni hash valide, comunque. Ovviamente non è normale prendere fette di lunghezza uno, ma è certamente valido.

Vedi la sezione slice di perldata perldoc per ulteriori informazioni sull'affettatura in Perl.

Le persone hanno già sottolineato che puoi avere sezioni e contesti, ma i sigilli sono lì per separare le cose che sono variabili da tutto il resto. Non è necessario conoscere tutte le parole chiave o i nomi delle subroutine per scegliere un nome di variabile sensibile. È una delle grandi cose che mi manca di Perl in altre lingue.

Mi viene in mente un modo

$x = myarray[1];

è ambiguo - e se volessi un array chiamato m?

$x = m[1];

Come puoi dirlo a parte una partita regex?

In altre parole, la sintassi è lì per aiutare l'interprete Perl, beh, interpretare!

In Perl 5 (da modificare in Perl 6) un sigillo indica il contesto della tua espressione.

  • Desideri un particolare scalare da un hash, quindi è $hash{key}.
  • Vuoi che il valore di un determinato slot sia fuori da un array, quindi è $array[0].

Tuttavia, come sottolineato da zigdon, sezioni sono legali. Interpretano quelle espressioni in un contesto elenco .

  • Si desidera un elenco di 1 valore in un hash @hash{key} funziona
  • Ma funzionano anche elenchi più grandi, come @hash{qw<key1 key2 ... key_n>}.

  • Desideri un paio di slot da un array @array[0,3,5..7,$n..$n+5] funziona

  • @array[0] è un elenco di dimensioni 1.

Non c'è " hash context " ;, quindi né %hash{@keys}%hash{key} hanno significato.

Quindi hai "@" + "array[0]" < = > lt &; sigil = contesto > + < espressione di indicizzazione > come espressione completa.

Il sigillo fornisce il contesto per l'accesso:

  • $ significa contesto scalare (uno scalare variabile o un singolo elemento di un hash o di un array)
  • @ significa contesto elenco (un intero array o una porzione di un hash o un array)
  • % è un intero hash

In Perl 5 hai bisogno dei sigilli ($ e @) perché l'interpretazione predefinita dell'identificatore bareword è quella di una chiamata di subroutine (eliminando così la necessità di usare & amp; nella maggior parte dei casi).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top