Ricerca…


Sintassi

  • mia # dichiarazione lessicale
  • la nostra # dichiarazione globale
  • $ pippo # Scalare
  • @foo # Array
  • $ # foo # Array Ultimo indice
  • % foo # Hash
  • $ {$ pippo} # Deferimento scalare
  • @ {$ pippo} # De-riferimento dell'array
  • $ # {$ foo} # Array-DeRef Last-Index
  • % {$ foo} # De-riferimento di hash
  • $ foo [$ index] # Array viene indicizzato
  • $ {$ pippo} [$ indice] # De-riferimento dell'array e reso indicizzato.
  • $ pippo -> [$ indice] # Array De-Reference e get indexed (semplificato)
  • $ foo {$ chiave} # Hash ottiene il valore per la chiave
  • $ {$ foo} {$ key} # Hash Dereference e ottieni valore per la chiave
  • $ pippo -> {$ chiave} # Hash Dereference e ottieni il valore per la chiave (semplificato)
  • \ $ x # Riferimento a Scalare
  • \ @x # Riferimento alla matrice
  • \% x # Riferimento a hash
  • = [] # Riferimento a matrice anonima (In linea)
  • = {} # Riferimento a Hash anonimo (In linea)

scalari

Gli scalari sono il tipo di dati di base di Perl. Sono contrassegnati con il sigillo $ e contengono un singolo valore di uno dei tre tipi:

  • un numero ( 3 , 42 , 3.141 , ecc.)
  • una stringa ( 'hi' , "abc" , ecc.)
  • un riferimento a una variabile (vedi altri esempi).
my $integer = 3;                      # number
my $string = "Hello World";           # string
my $reference = \$string;             # reference to $string

Perl converte istantaneamente numeri e stringhe , in base a ciò che un particolare operatore si aspetta.

my $number = '41';                    # string '41'
my $meaning = $number + 1;            # number  42
my $sadness = '20 apples';            # string '20 apples'
my $danger = $sadness * 2;            # number '40', raises warning

Quando converti una stringa in un numero, Perl prende tutte le cifre dalla parte anteriore di una stringa come può, quindi perché 20 apples vengono convertite in 20 nell'ultima riga.

In base al fatto se si desidera trattare il contenuto di uno scalare come una stringa o un numero, è necessario utilizzare operatori diversi. Non mescolarli.

# String comparison                   # Number comparison
'Potato' eq 'Potato';                 42 == 42;
'Potato' ne 'Pomato';                 42 != 24;
'Camel'  lt 'Potato';                 41 < 42;
'Zombie' gt 'Potato';                 43 > 42;

# String concatenation                # Number summation
'Banana' . 'phone';                   23 + 19;

# String repetition                   # Number multiplication 
'nan' x 3;                            6 * 7;

Il tentativo di utilizzare le operazioni con le stringhe sui numeri non solleverà gli avvisi; tentare di utilizzare le operazioni numeriche su stringhe non numeriche. Tieni presente che alcune stringhe non numeriche come 'inf' , 'nan' , '0 but true' contano come numeri.

Array

Gli array memorizzano una sequenza di valori ordinati. È possibile accedere ai contenuti per indice o scorrere su di essi. I valori rimarranno nell'ordine in cui li hai riempiti.

my @numbers_to_ten = (1,2,3,4,5,6,7,8,9,10); # More conveniently: (1..10)
my @chars_of_hello = ('h','e','l','l','o');
my @word_list = ('Hello','World');

# Note the sigil: access an @array item with $array[index]
my $second_char_of_hello = $chars_of_hello[1]; # 'e'

# Use negative indices to count from the end (with -1 being last)
my $last_char_of_hello = $chars_of_hello[-1];

# Assign an array to a scalar to get the length of the array
my $length_of_array = @chars_of_hello; # 5

# You can use $# to get the last index of an array, and confuse Stack Overflow
my $last_index_of_array = $#chars_of_hello; # 4

# You can also access multiple elements of an array at the same time
# This is called "array slice"
# Since this returns multiple values, the sigil to use here on the RHS is @
my @some_chars_of_hello = @chars_of_hello[1..3]; # ('H', 'e', 'l')
my @out_of_order_chars = @chars_of_hello[1,4,2]; # ('e', 'o', 'l')

# In Python you can say array[1:-1] to get all elements but first and last
# Not so in Perl: (1..-1) is an empty list. Use $# instead
my @empty_list = @chars_of_hello[1..-1];                           # ()
my @inner_chars_of_hello = @chars_of_hello[1..$#chars_of_hello-1]; # ('e','l','l')

# Access beyond the end of the array yields undef, not an error
my $undef = $chars_of_hello[6]; # undef    

Gli array sono mutabili:

use utf8; # necessary because this snippet is utf-8
$chars_of_hello[1] = 'u';              #     ('h','u','l','l','o')
push @chars_of_hello, ('!', '!');      #     ('h','u','l','l','o','!','!')
pop @chars_of_hello;                   #     ('h','u','l','l','o','!')
shift @chars_of_hello;                 #         ('u','l','l','o','!')
unshift @chars_of_hello, ('¡', 'H');   # ('¡','H','u','l','l','o','!')
@chars_of_hello[2..5] = ('O','L','A'); # ('¡','H','O','L','A',undef,'!') whoops! 
delete $chars_of_hello[-2];            # ('¡','H','O','L','A',      '!')

# Setting elements beyond the end of an array does not result in an error
# The array is extended with undef's as necessary. This is "autovivification."
my @array;           # ()
my @array[3] = 'x';  # (undef, undef, undef, 'x')

Infine, puoi eseguire il looping del contenuto di un array:

use v5.10; # necessary for 'say'
for my $number (@numbers_to_ten) {
  say $number ** 2;
}

Se usati come booleani, gli array sono veri se non sono vuoti.

hash

Gli hash possono essere intesi come tabelle di ricerca. Puoi accedere ai suoi contenuti specificando una chiave per ognuno di essi. Le chiavi devono essere stringhe. Se non lo sono, saranno convertiti in stringhe.

Se dai l'hash semplicemente una chiave conosciuta, ti servirà il suo valore.

# Elements are in (key, value, key, value) sequence
my %inhabitants_of = ("London", 8674000, "Paris", 2244000);

# You can save some typing and gain in clarity by using the "fat comma"
# syntactical sugar. It behaves like a comma and quotes what's on the left.
my %translations_of_hello = (spanish => 'Hola', german => 'Hallo', swedish => 'Hej'); 

Nell'esempio seguente, annota parentesi e sigillo: accedi a un elemento di %hash utilizzando $hash{key} perché il valore che desideri è uno scalare. Alcuni ritengono buona pratica citare la chiave mentre altri trovano questo stile visivamente rumoroso. La quotazione è richiesta solo per le chiavi che potrebbero essere scambiate per espressioni come $hash{'some-key'}

my $greeting = $translations_of_hello{'spanish'};

Mentre Perl per impostazione predefinita proverà ad usare le bareword come stringhe, + modificatore può anche essere usato per indicare a Perl che la chiave non dovrebbe essere interpolata ma eseguita con il risultato dell'esecuzione usata come chiave:

my %employee = ( name => 'John Doe', shift => 'night' );
# this example will print 'night'
print $employee{shift}; 

# but this one will execute [shift][1], extracting first element from @_,
# and use result as a key
print $employee{+shift};

Come con gli array, è possibile accedere a più elementi hash contemporaneamente. Questo è chiamato una fetta di hash . Il valore risultante è una lista, quindi usa @ sigil:

my @words = @translations_of_hello{'spanish', 'german'}; # ('Hola', 'Hallo')

Scandire le chiavi di un hash con keys keys tornerà articoli in un ordine casuale. Combina con sort se lo desideri.

for my $lang (sort keys %translations_of_hello) {
  say $translations_of_hello{$lang};
}

Se non hai effettivamente bisogno delle chiavi come nell'esempio precedente, i values restituiscono direttamente i valori dell'hash:

for my $translation (values %translations_of_hello) {
  say $translation;
}

Puoi anche usare un ciclo while con each per scorrere l'hash. In questo modo, otterrete sia la chiave che il valore allo stesso tempo, senza una ricerca separata del valore. Il suo uso è tuttavia scoraggiato, poiché each può rompere in modi mistificatori.

# DISCOURAGED
while (my ($lang, $translation) = each %translations_of_hello) {
  say $translation;
}

L'accesso agli elementi non impostati restituisce undef, non un errore:

my $italian = $translations_of_hello{'italian'}; # undef

map e lista di appiattimento possono essere usati per creare hash degli array. Questo è un modo popolare per creare un "set" di valori, ad esempio per verificare rapidamente se un valore è in @elems . Questa operazione normalmente richiede O (n) tempo (cioè proporzionale al numero di elementi) ma può essere eseguita in tempo costante (O (1)) trasformando la lista in un hash:

@elems = qw(x y x z t);
my %set = map { $_ => 1 } @elems;   # (x, 1, y, 1, t, 1)
my $y_membership = $set{'y'};       # 1
my $w_membership = $set{'w'};       # undef

Questo richiede qualche spiegazione. I contenuti di @elems vengono letti in una lista, che viene elaborata dalla map . map accetta un blocco di codice che viene chiamato per ogni valore della sua lista di input; il valore dell'elemento è disponibile per l'uso in $_ . Il nostro blocco di codice restituisce due elementi di elenco per ciascun elemento di input: $_ , l'elemento di input e 1 , solo un valore. Una volta che l'account per l'appiattimento della lista, il risultato è che la map { $_ => 1 } @elems trasforma qw(xyxzt) in (x => 1, y => 1, x => 1, z => 1, t => 1) .

Man mano che quegli elementi vengono assegnati all'hash, gli elementi dispari diventano chiavi hash e persino gli elementi diventano valori hash. Quando una chiave viene specificata più volte in un elenco da assegnare a un hash, vince l' ultimo valore. Ciò elimina in modo efficace i duplicati.

Un modo più rapido per trasformare una lista in un hash usa l'assegnazione ad una slice hash. Usa l'operatore x per moltiplicare la lista di elementi singoli (1) per la dimensione di @elems , quindi c'è un valore 1 per ciascuna delle chiavi nella sezione sul lato sinistro:

@elems = qw(x y x z t);
my %set;
@set{@elems} = (1) x @elems;

La seguente applicazione di hash sfrutta anche il fatto che gli hash e gli elenchi possono essere spesso usati in modo intercambiabile per implementare argomenti con funzioni nominate:

sub hash_args {
  my %args = @_;
  my %defaults = (foo => 1, bar => 0);
  my %overrides = (__unsafe => 0);
  my %settings = (%defaults, %args, %overrides);
}

# This function can then be called like this:
hash_args(foo => 5, bar => 3); # (foo => 5, bar => 3, __unsafe ==> 0)
hash_args();                   # (foo => 1, bar => 0, __unsafe ==> 0)
hash_args(__unsafe => 1)       # (foo => 1, bar => 0, __unsafe ==> 0)

Se usati come booleani, gli hash sono veri se non sono vuoti.

Riferimenti scalari

Un riferimento è una variabile scalare (una prefissata da $ ) che "fa riferimento a" altri dati.

my $value     = "Hello";
my $reference = \$value;
print $value;     # => Hello
print $reference; # => SCALAR(0x2683310)

Per ottenere i dati di riferimento, puoi de-referenziare .

say ${$reference};                  # Explicit prefix syntax
say $$reference;                    # The braces can be left out (confusing)
5.24.0

Nuova sintassi di dereference postfix, disponibile per impostazione predefinita dalla v5.24

use v5.24;
say $reference->$*; # New postfix notation

Questo "valore de-referenziato" può quindi essere modificato come se fosse la variabile originale.

${$reference} =~ s/Hello/World/;
print ${$reference};  # => World
print $value;         # => World

Un riferimento è sempre vero , anche se il valore a cui si riferisce è falsy (come 0 o "" ).

Potresti volere un riferimento scalare se:

  • Vuoi passare una stringa a una funzione e modificarla per te senza che sia un valore di ritorno.

  • Desiderate evitare esplicitamente che Perl copi in modo implicito il contenuto di una stringa di grandi dimensioni a un certo punto del passaggio della vostra funzione (particolarmente rilevante per i vecchi Perls senza stringhe copy-on-write)

  • Desiderate disambiguare valori simili a stringhe con un significato specifico, da stringhe che trasmettono contenuti, ad esempio:

    • Disambigui un nome di file dal contenuto del file
    • Disambigura il contenuto restituito da una stringa di errore restituita
  • Desiderate implementare un modello di oggetto interno e leggero, in cui gli oggetti consegnati al codice chiamante non portano i metadati visibili dell'utente:

    our %objects;
    my $next_id = 0;
    sub new { 
       my $object_id = $next_id++;
       $objects{ $object_id } = { ... }; # Assign data for object
       my $ref = \$object_id;
       return bless( $ref, "MyClass" );
    }
    

Riferimenti di matrice

I riferimenti di matrice sono scalari ( $ ) che si riferiscono agli array.

my @array = ("Hello"); # Creating array, assigning value from a list
my $array_reference = \@array;

Questi possono essere creati più a mano corta come segue:

my $other_array_reference = ["Hello"];

La modifica / l'uso dei riferimenti di array richiede prima il dereferenziamento.

my @contents = @{ $array_reference };               # Prefix notation
my @contents = @$array_reference;                   # Braces can be left out
5.24.0

Nuova sintassi di dereference postfix, disponibile per impostazione predefinita dalla v5.24

use v5.24;
my @contents = $array_reference->@*; # New postfix notation 

Quando accedi ai contenuti di un arrayref per indice puoi usare lo zucchero -> sintattico.

my @array = qw(one two three);      my $arrayref = [ qw(one two three) ]
my $one = $array[0];                my $one = $arrayref->[0];

A differenza degli array, arrayrefs può essere nidificato:

my @array = ( (1, 0), (0, 1) )  # ONE array of FOUR elements: (1, 0, 0, 1)
my @matrix = ( [1, 0], [0, 1] ) # an array of two arrayrefs
my $matrix = [ [0, 1], [1, 0] ] # an arrayref of arrayrefs
# There is no namespace conflict between scalars, arrays and hashes
# so @matrix and $matrix _both_ exist at this point and hold different values.

my @diagonal_1 = ($matrix[0]->[1], $matrix[1]->[0])     # uses @matrix
my @diagonal_2 = ($matrix->[0]->[1], $matrix->[1]->[0]) # uses $matrix
# Since chained []- and {}-access can only happen on references, you can
# omit some of those arrows.
my $corner_1 = $matrix[0][1];   # uses @matrix;
my $corner_2 = $matrix->[0][1]; # uses $matrix;  

Se usato come booleano, i riferimenti sono sempre veri.

Riferimenti hash

I riferimenti hash sono scalari che contengono un puntatore alla posizione di memoria contenente i dati di un hash. Poiché lo scalare punta direttamente all'hash stesso, quando viene passato a una subroutine, le modifiche apportate all'hash non sono locali alla subroutine come con un normale hash, ma sono globali.

Per prima cosa, esaminiamo cosa succede quando passi un normale hash a una subroutine e lo modifichi lì dentro:

use strict;
use warnings;
use Data::Dumper;

sub modify
{
    my %hash = @_;

    $hash{new_value} = 2;

    print Dumper("Within the subroutine");
    print Dumper(\%hash);

    return;
}

my %example_hash = (
    old_value   => 1,
);

modify(%example_hash);

print Dumper("After exiting the subroutine");
print Dumper(\%example_hash);

Quale risulta in:

$VAR1 = 'Within the subroutine';
$VAR1 = {
          'new_value' => 2,
          'old_value' => 1
        };
$VAR1 = 'After exiting the subroutine';
$VAR1 = {
          'old_value' => 1
        };

Si noti che, una volta usciti dalla subroutine, l'hash rimane inalterato; tutte le modifiche ad esso erano locali alla subroutine di modifica, perché abbiamo passato una copia dell'hash, non l'hash stesso.

In confronto, quando si passa un hashref, si passa l'indirizzo all'hash originale, quindi tutte le modifiche apportate all'interno della subroutine verranno apportate all'hash originale:

use strict;
use warnings;
use Data::Dumper;

sub modify
{
    my $hashref = shift;

    # De-reference the hash to add a new value
    $hashref->{new_value} = 2;

    print Dumper("Within the subroutine");
    print Dumper($hashref);

    return;
}

# Create a hashref
my $example_ref = {
    old_value   => 1,
};

# Pass a hashref to a subroutine
modify($example_ref);

print Dumper("After exiting the subroutine");
print Dumper($example_ref);

Ciò comporterà:

$VAR1 = 'Within the subroutine';
$VAR1 = {
          'new_value' => 2,
          'old_value' => 1
        };
$VAR1 = 'After exiting the subroutine';
$VAR1 = {
          'new_value' => 2,
          'old_value' => 1
        };

Typeglobs, ref typeglob, filehandle e costanti

Un typeglob *foo contiene riferimenti al contenuto delle variabili globali con quel nome: $foo , @foo , $foo , &foo , ecc. Puoi accedervi come un hash e assegnare per manipolare direttamente le tabelle dei simboli (male!).

use v5.10; # necessary for say
our $foo = "foo";
our $bar;
say ref *foo{SCALAR};     # SCALAR
say ${ *foo{SCALAR} };    # bar
*bar = *foo;
say $bar;                 # bar
$bar = 'egg';
say $foo;                 # egg

I typeglob sono più comunemente gestiti quando si tratta di file. open , ad esempio, produce un riferimento a un typeglob quando viene richiesto di creare un filehandle non globale:

use v5.10; # necessary for say
open(my $log, '> utf-8', '/tmp/log') or die $!; # open for writing with encoding
say $log 'Log opened';

# You can dereference this globref, but it's not very useful.
say ref $log;                   # GLOB
say (*{$log}->{IO} // 'undef'); # undef

close $log or die $!;

I typeglob possono anche essere usati per creare variabili globali di sola lettura, sebbene l' use constant sia in uso più ampio.

# Global constant creation
*TRUE = \('1');
our $TRUE;
say $TRUE;  # 1
$TRUE = ''; # dies, "Modification of a read-only value attempted"

# use constant instead defines a parameterless function, therefore it's not global,
# can be used without sigils, can be imported, but does not interpolate easily.
use constant (FALSE => 0);
say FALSE;        # 0
say &FALSE;       # 0
say "${\FALSE}";  # 0 (ugh)
say *FALSE{CODE}; # CODE(0xMA1DBABE)

# Of course, neither is truly constant when you can manipulate the symbol table...
*TRUE = \('');
use constant (EVIL => 1);
*FALSE = *EVIL;

sigilli

Perl ha un numero di sigilli:

$scalar = 1; # individual value
@array = ( 1, 2, 3, 4, 5 ); # sequence of values
%hash = ('it', 'ciao', 'en', 'hello', 'fr', 'salut'); # unordered key-value pairs
&function('arguments'); # subroutine
*typeglob; # symbol table entry

Questi sembrano sigilli, ma non lo sono:

\@array; # \ returns the reference of what's on the right (so, a reference to @array)
$#array; # this is the index of the last element of @array

Puoi usare parentesi dopo il sigillo se dovessi essere così incline. Occasionalmente, questo migliora la leggibilità.

say ${value} = 5;

Mentre si utilizzano sigilli diversi per definire variabili di tipi diversi, è possibile accedere alla stessa variabile in diversi modi in base a quali sigilli si utilizzano.

%hash;            # we use % because we are looking at an entire hash
$hash{it};        # we want a single value, however, that's singular, so we use $
$array[0];        # likewise for an array. notice the change in brackets.
@array[0,3];      # we want multiple values of an array, so we instead use @
@hash{'it','en'}; # similarly for hashes (this gives the values: 'ciao', 'hello')
%hash{'it','fr'}; # we want an hash with just some of the keys, so we use %
                  # (this gives key-value pairs: 'it', 'ciao', 'fr', 'salut')

Questo è particolarmente vero per i riferimenti. Per utilizzare un valore referenziato è possibile combinare insieme i sigilli.

my @array = 1..5;                    # This is an array
my $reference_to_an_array = \@array; # A reference to an array is a singular value
push @array, 6;                      # push expects an array
push @$reference_to_an_array, 7;     # the @ sigil means what's on the right is an array
                                     # and what's on the right is $reference_to_an_array
                                     # hence: first a @, then a $

Ecco un modo forse meno confusionario per pensarci. Come abbiamo visto in precedenza, puoi usare le parentesi graffe per avvolgere ciò che si trova a destra di un sigillo. Quindi puoi pensare a @{} come qualcosa che prende un riferimento di matrice e ti dà l'array di riferimento.

# pop does not like array references
pop $reference_to_an_array; # ERROR in Perl 5.20+
# but if we use @{}, then...
pop @{ $reference_to_an_array }; # this works!

A quanto pare, @{} accetta effettivamente un'espressione:

my $values = undef;
say pop @{ $values };       # ERROR: can't use undef as an array reference
say pop @{ $values // [5] } # undef // [5] gives [5], so this prints 5

... e lo stesso trucco funziona anche per altri sigilli.

# This is not an example of good Perl. It is merely a demonstration of this language feature
my $hashref = undef;
for my $key ( %{ $hashref // {} } ) {
  "This doesn't crash";
}

... ma se l'argomento di un sigillo è semplice, puoi lasciare le parentesi.

say $$scalar_reference;
say pop @$array_reference;
for keys (%$hash_reference) { ... };

Le cose possono diventare eccessivamente stravaganti. Funziona, ma ti preghiamo Perl responsabilmente.

my %hash = (it => 'ciao', en => 'hi', fr => 'salut');
my $reference = \%hash;
my $reference_to_a_reference = \$reference;

my $italian = $hash{it};                              # Direct access 
my @greets = @$reference{'it', 'en'};                 # Dereference, then access as array
my %subhash = %$$reference_to_a_reference{'en', 'fr'} # Dereference ×2 then access as hash

Per la maggior parte dei normali usi, puoi semplicemente usare i nomi delle subroutine senza un sigillo. (Le variabili senza un sigillo sono in genere chiamate "bareword".) Il & sigil è utile solo in un numero limitato di casi.

  • Fare riferimento a una subroutine:

    sub many_bars { 'bar' x $_[0] }
    my $reference = \&many_bars;
    say $reference->(3); # barbarbar
    
  • Chiamare una funzione ignorando il suo prototipo.

  • Combinato con goto, come una chiamata di funzione un po 'strana che ha il frame di chiamata corrente sostituito con il chiamante. Pensa alla chiamata API di Linux exec() , ma per le funzioni.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow