Buscar..


Sintaxis

  • mi # declaración léxica
  • nuestra # declaración global
  • $ foo # escalar
  • @foo # Array
  • $ # foo # Array Last-Index
  • % foo # Hash
  • $ {$ foo} # Decalar referencia
  • @ {$ foo} # Array De-Reference
  • $ # {$ foo} # Array-DeRef Last-Index
  • % {$ foo} # Hash De-Reference
  • $ foo [$ index] # Array se indexa
  • $ {$ foo} [$ index] # Array De-Reference y se indexa.
  • $ foo -> [$ index] # Array De-Reference y se indexa (simplificado)
  • $ foo {$ clave} # Hash obtener valor por clave
  • $ {$ foo} {$ clave} # Hash Dereference y obtener valor por clave
  • $ foo -> {$ clave} # Hash Dereference y obtener valor por clave (simplificado)
  • \ $ x # Referencia a escalar
  • \ @x # Referencia a Array
  • \% x # Referencia al hash
  • = [] # Referencia a una matriz anónima (en línea)
  • = {} # Referencia a Hash anónimo (en línea)

Escalares

Los escalares son el tipo de datos más básico de Perl. Están marcados con el sigil $ y tienen un solo valor de uno de tres tipos:

  • un número ( 3 , 42 , 3.141 , etc.)
  • una cadena ( 'hi' , "abc" , etc.)
  • una referencia a una variable (ver otros ejemplos).
my $integer = 3;                      # number
my $string = "Hello World";           # string
my $reference = \$string;             # reference to $string

Perl convierte entre números y cadenas sobre la marcha , según lo que espera un operador en particular.

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

Al convertir una cadena en un número, Perl toma tantos dígitos del frente de una cadena como puede, de ahí que 20 apples se conviertan en 20 en la última línea.

En función de si desea tratar el contenido de un escalar como una cadena o un número, debe utilizar diferentes operadores. No los mezcle.

# 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;

Intentar usar operaciones de cadena en números no generará advertencias; intentar usar operaciones numéricas en cadenas no numéricas lo hará. Tenga en cuenta que algunas cadenas sin dígitos, como 'inf' , 'nan' , '0 but true' cuentan como números.

Arrays

Las matrices almacenan una secuencia ordenada de valores. Puede acceder a los contenidos por índice, o iterar sobre ellos. Los valores se mantendrán en el orden en que los completó.

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    

Las matrices son mutables:

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')

Finalmente, puedes recorrer el contenido de una matriz:

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

Cuando se usan como valores booleanos, las matrices son verdaderas si no están vacías.

Hashes

Hashes puede entenderse como tablas de búsqueda. Puedes acceder a su contenido especificando una clave para cada uno de ellos. Las llaves deben ser cadenas. Si no lo son, se convertirán en cadenas.

Si le da al hash simplemente una clave conocida, le servirá su valor.

# 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'); 

En el siguiente ejemplo, note los corchetes y el sigilo: accede a un elemento de %hash usando $hash{key} porque el valor que desea es un escalar. Algunos consideran una buena práctica citar la clave, mientras que otros encuentran este estilo visualmente ruidoso. Solo se requieren citas para las claves que podrían confundirse con expresiones como $hash{'some-key'}

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

Mientras que Perl por defecto intentará usar las palabras peladas como cadenas, el modificador + también se puede usar para indicar a Perl que la clave no debe interpolarse sino ejecutarse, y el resultado de la ejecución se usa como una clave:

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

Al igual que con las matrices, puede acceder a varios elementos hash al mismo tiempo. Esto se llama una porción de hash . El valor resultante es una lista, así que use @ sigil:

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

Iterar sobre las claves de un hash con keys keys devolverá los elementos en un orden aleatorio. Combina con el sort si lo deseas.

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

Si no necesita las claves como en el ejemplo anterior, los values devuelven los valores de hash directamente:

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

También puede usar un bucle while con each para iterar sobre el hash. De esta manera, obtendrá la clave y el valor al mismo tiempo, sin una búsqueda de valor por separado. Sin embargo, se desaconseja su uso, ya que each puede romper en formas de confusión.

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

El acceso a los elementos no configurados devuelve undef, no un error:

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

map y el aplanamiento de listas se pueden utilizar para crear hashes a partir de matrices. Esta es una forma popular de crear un 'conjunto' de valores, por ejemplo, para verificar rápidamente si un valor está en @elems . Esta operación generalmente toma tiempo O (n) (es decir, proporcional al número de elementos) pero se puede hacer en tiempo constante (O (1)) al convertir la lista en 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

Esto requiere alguna explicación. El contenido de @elems se lee en una lista, que se procesa por map . map acepta un bloque de código al que se llama para cada valor de su lista de entrada; El valor del elemento está disponible para su uso en $_ . Nuestro bloque de código devuelve dos elementos de lista para cada elemento de entrada: $_ , el elemento de entrada y 1 , solo un valor. Una vez que tenga en cuenta el aplanamiento de listas, el resultado es que el map { $_ => 1 } @elems convierte qw(xyxzt) en (x => 1, y => 1, x => 1, z => 1, t => 1) .

A medida que esos elementos se asignan al hash, los elementos impares se convierten en claves hash e incluso los elementos se convierten en valores hash. Cuando se especifica una clave varias veces en una lista para asignarla a un hash, el último valor gana. Esto efectivamente descarta los duplicados.

Una forma más rápida de convertir una lista en un hash usa la asignación a una porción de hash. Utiliza el operador x para multiplicar la lista de un solo elemento (1) por el tamaño de @elems , por lo que hay un valor de 1 para cada una de las claves en el sector en el lado izquierdo:

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

La siguiente aplicación de hashes también explota el hecho de que los hashes y las listas a menudo se pueden usar indistintamente para implementar la función nombrada args:

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)

Cuando se usan como valores booleanos, los hashes son verdaderos si no están vacíos.

Referencias escalares

Una referencia es una variable escalar (una prefijada por $ ) que "se refiere a" algunos otros datos.

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

Para obtener los datos referidos, usted de referencia .

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

Nueva sintaxis de desreferenciación de postfix, disponible por defecto desde v5.24

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

Este "valor sin referencia" se puede cambiar como si fuera la variable original.

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

Una referencia es siempre veraz , incluso si el valor al que se refiere es falsy (como 0 o "" ).

Es posible que desee una referencia escalar si:

  • Desea pasar una cadena a una función y hacer que la modifique para usted sin que sea un valor de retorno.

  • Desea evitar explícitamente que Perl copie implícitamente el contenido de una cadena grande en algún punto de su paso de funciones (especialmente relevante en Perls anteriores sin cadenas de copia en escritura)

  • Desea desambiguar los valores de tipo cadena con un significado específico, a partir de cadenas que transmiten contenido, por ejemplo:

    • Desambiguar un nombre de archivo del contenido del archivo
    • Desambiguar el contenido devuelto de una cadena de error devuelta
  • Desea implementar un modelo de objetos ligero de adentro hacia afuera, donde los objetos entregados al código de llamada no lleven metadatos visibles para el usuario:

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

Referencias de Array

Las Referencias de Array son escalares ( $ ) que se refieren a Arrays.

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

Estos pueden ser creados más cortos de la siguiente manera:

my $other_array_reference = ["Hello"];

La modificación / uso de las referencias de matriz requiere primero la eliminación de referencias.

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

Nueva sintaxis de desreferenciación de postfix, disponible por defecto desde v5.24

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

Al acceder a los contenidos de un arrayref por índice, puede utilizar el -> azúcar sintáctica.

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

A diferencia de los arrays, arrayrefs puede ser anidado:

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;  

Cuando se usa como booleano, las referencias son siempre ciertas.

Hash Referencias

Las referencias de hash son escalares que contienen un puntero a la ubicación de memoria que contiene los datos de un hash. Debido a que el escalar apunta directamente al hash, cuando se pasa a una subrutina, los cambios realizados en el hash no son locales a la subrutina como ocurre con un hash normal, sino que son globales.

Primero, examinemos lo que sucede cuando pasas un hash normal a una subrutina y lo modificamos allí:

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);

Lo que resulta en:

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

Observe que después de salir de la subrutina, el hash permanece inalterado; todos los cambios fueron locales a la subrutina de modificación, porque pasamos una copia del hash, no el hash en sí.

En comparación, cuando se pasa un hashref, se pasa la dirección al hash original, por lo que cualquier cambio realizado dentro de la subrutina se hará al hash original:

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);

Esto resultará en:

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

Typeglobs, typeglob refs, manejadores de archivos y constantes

Un typeglob *foo contiene referencias a los contenidos de las variables globales con ese nombre: $foo , @foo , $foo , &foo , etc. Puedes acceder a él como un hash y asignarlo para manipular las tablas de símbolos directamente (¡malvado!).

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

Los typeglobs se manejan más comúnmente cuando se trata de archivos. open , por ejemplo, produce una referencia a un typeglob cuando se le pide que cree un identificador de archivo no global:

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 $!;

Los typeglobs también se pueden usar para hacer variables globales de solo lectura, aunque el use constant es un uso más amplio.

# 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;

Sigilos

Perl tiene una serie de sigilos:

$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

Estos parecen sigilos, pero no son

\@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

Puedes usar llaves después del sigilo si así lo deseas. Ocasionalmente, esto mejora la legibilidad.

say ${value} = 5;

Mientras usa diferentes sigilos para definir variables de diferentes tipos, se puede acceder a la misma variable de diferentes maneras en función de los sigilos que use.

%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')

Esto es especialmente cierto de las referencias. Para utilizar un valor de referencia, puede combinar los sigilos juntos.

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 $

Aquí hay una manera quizás menos confusa de pensar en ello. Como vimos anteriormente, puedes usar llaves para envolver lo que está a la derecha de un sigilo. Así que puedes pensar en @{} como algo que toma una referencia de matriz y te da la matriz de referencia.

# 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!

Como resultado, @{} realidad acepta una expresión:

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

... y el mismo truco funciona para otros sigilos, también.

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

... pero si el "argumento" a un sigilo es simple, puedes dejar las llaves.

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

Las cosas pueden volverse excesivamente extravagantes. Esto funciona, pero por favor Perl responsablemente.

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

Para el uso más normal, puede usar nombres de subrutina sin un sigilo. (Las variables sin un sigilo generalmente se llaman "palabras peladas"). El & sigil solo es útil en un número limitado de casos.

  • Haciendo referencia a una subrutina:

    sub many_bars { 'bar' x $_[0] }
    my $reference = \&many_bars;
    say $reference->(3); # barbarbar
    
  • Llamando a una función ignorando su prototipo.

  • Combinado con goto, como una llamada de función un poco rara que tiene el marco de llamada actual reemplazado con la persona que llama. Piense en la llamada a la API de Linux exec() , pero para las funciones.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow