Buscar..


Array como lista

La matriz es uno de los tipos de variables básicas de Perl. Contiene una lista, que es una secuencia ordenada de cero o más escalares. La matriz es la variable que contiene (y proporciona acceso a) los datos de la lista, como se documenta en perldata .

Puede asignar una lista a una matriz:

my @foo = ( 4, 5, 6 );

Puede usar una matriz donde se espera una lista:

join '-', ( 4, 5, 6 );
join '-', @foo;

Algunos operadores solo trabajan con matrices, ya que mutan la lista que contiene:

shift @array;
unshift @array, ( 1, 2, 3 );
pop @array;
push @array, ( 7, 8, 9 );

Asignando una lista a un hash

Las listas también se pueden asignar a las variables hash. Al crear una lista que se asignará a una variable hash, se recomienda usar la coma grande => entre las claves y los valores para mostrar su relación:

my %hash = ( foo => 42, bar => 43, baz => 44 );

El => es realmente solo una coma especial que cita automáticamente el operando a su izquierda. Entonces, podrías usar comas normales, pero la relación no es tan clara:

my %hash = ( 'foo', 42, 'bar', 43, 'baz', 44 );

También puede usar cadenas entre comillas para el operando de la mano izquierda de la coma grasa => , que es especialmente útil para las claves que contienen espacios.

my %hash = ( 'foo bar' => 42, 'baz qux' => 43 );

Para obtener más información, consulte Operador de coma en perldoc perlop .

Las listas se pueden pasar a subrutinas

Para pasar la lista a una subrutina, debe especificar el nombre de la subrutina y luego proporcionarle la lista:

test_subroutine( 'item1', 'item2' );
test_subroutine  'item1', 'item2';     # same

Internamente, Perl @_ alias para esos argumentos y los coloca en la matriz @_ que está disponible dentro de la subrutina:

@_ =  ( 'item1', 'item2' ); # Done internally by perl

Se accede a argumentos de subrutina como este:

sub test_subroutine {
    print $_[0]; # item1
    print $_[1]; # item2
}

El alias le permite cambiar el valor original del argumento pasado a la subrutina:

sub test_subroutine {
    $_[0] +=  2;
}

my $x =  7;
test_subroutine( $x );
print $x; # 9

Para evitar cambios inadvertidos de valores originales pasados ​​a su subrutina, debe copiarlos:

sub test_subroutine {
    my( $copy_arg1, $copy_arg2 ) =  @_;
    $copy_arg1 += 2;
}

my $x =  7;
test_subroutine $x; # in this case $copy_arg2 will have `undef` value
print $x; # 7

Para probar cuántos argumentos se pasaron a la subrutina, verifique el tamaño de @_

sub test_subroutine {
    print scalar @_, ' argument(s) passed into subroutine';
}

Si pasas los argumentos de matriz a una subrutina, todos serán aplanados :

my @x =  ( 1, 2, 3 );
my @y =  qw/ a b c /; # ( 'a', 'b', 'c' )
test_some_subroutine @x, 'hi', @y; # 7 argument(s) passed into subroutine
# @_ =  ( 1, 2, 3, 'hi', 'a', 'b', 'c' ) # Done internally for this call

Si su test_some_subroutine contiene la instrucción $_[4] = 'd' , para la llamada anterior causará que $y[0] tenga un valor d después:

print "@y"; # d b c

Lista de retorno de subrutina

Por supuesto, puede devolver listas de subs:

sub foo {
    my @list1 =  ( 1, 2, 3 );
    my @list2 =  ( 4, 5 );

    return    ( @list1, @list2 );
}

my @list =  foo();
print @list;          # 12345

Pero no es la forma recomendada de hacerlo a menos que sepa lo que está haciendo.

Si bien esto está bien cuando el resultado está en el contexto LISTA , en el contexto SCALAR las cosas no están claras. Echemos un vistazo a la siguiente línea:

print scalar foo();  # 2

¿Por qué 2 ? Que esta pasando?

  1. Debido a que foo() evaluó en el contexto SCALAR , esta lista ( @list1, @list2 ) también se evaluó en el contexto SCALAR
  2. En contexto SCALAR , LIST devuelve su último elemento. Aquí está @list2
  3. De nuevo en el contexto SCALAR , array @list2 devuelve el número de sus elementos. Aquí está el 2 .

En la mayoría de los casos, la estrategia correcta devolverá las referencias a las estructuras de datos .
Así que en nuestro caso deberíamos hacer lo siguiente:

 return    ( \@list1, \@list2 );

Luego, la persona que llama hace algo como esto para recibir los dos arrayrefs devueltos:

 my ($list1, $list2) = foo(...);

Usando arrayref para pasar array a sub

El arrayref para @foo es \@foo . Esto es útil si necesita pasar una matriz y otras cosas a una subrutina. Pasar a @foo es como pasar múltiples escalares. Pero pasar \@foo es un solo escalar. Dentro de la subrutina:

xyz(\@foo, 123);
...
sub xyz {
    my ($arr, $etc) = @_;
    print $arr->[0]; # using the first item in $arr. It is like $foo[0]

Hash como lista

En la lista el hash de contexto se aplana.

my @bar =  ( %hash, %hash );

La matriz @bar se inicializa con una lista de dos hashes de %hash

  • ambos %hash son aplanados
  • nueva lista se crea a partir de elementos aplanados
  • @bar array se inicializa con esa lista

Se garantiza que los pares clave-valor van juntos. Las claves siempre están indexadas, los valores son impares. No se garantiza que los pares clave-valor siempre se aplanen en el mismo orden:

my %hash =  ( a => 1, b => 2 );
print %hash; # Maybe 'a1b2' or 'b2a1'


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