Asignación Implícita de Memoria y Autovivificación

Partes Derechas

Cuando una variable de tipo lista se evalúa en una expresión se produce una copia de la misma. Observe el siguiente ejemplo:

DB<1> @a = 1..5
DB<2> $b = [ @a ]
DB<3> p $b
ARRAY(0x833f9a4)
DB<4> p @$b
12345
DB<5> @$b = 6..10
DB<6> p @a
12345
DB<7> p @$b
678910
En la línea 2 se crea una referencia a una copia del array @a. Si se quiere crear una referencia al array @a o a uno de sus elementos lo que debe ponerse en la parte derecha es la referencia al mismo:
lhp@nereida:~/Lperl/src$ perl -wde 0
main::(-e:1):   0
  DB<1> @a = 1..5
  DB<2> $b = \$a[3]
  DB<3> $$b = 9999
  DB<4> x @a
0  1
1  2
2  3
3  9999
4  5
  DB<5> $c = \@a
  DB<6> $c->[3] = -1
  DB<7> x @a
0  1
1  2
2  3
3  '-1'
4  5

Alojamiento Automático de Memoria

Otro ejemplo. Si la primera línea de nuestro guión Perl es algo como:

$task{ls}->{parameters}->[0] = "l";

Perl creará un hash de referencias task al cual asignará una clave ls y cuyo valor es una referencia a una entrada de un hash, que será creado con una clave parameters cuyo valor es una referencia a un array cuya entrada 0 es "l". La asignación de memoria es automática.

Autovivificación

Se denomina Autovivificación o Autovivification a la creación automática de una referencia cuando una valor indefinido es de-referenciado. El siguiente ejemplo ilustra una autovivificación:

lhp@nereida:~$ perl -de 0
DB<1> $href->{Fruit}->{Bananas}->{Yellow} = "In Season"
DB<2> print "Red Apples are not in season.\n" unless exists $href->{Fruit}->{Apples}->{Red}
Red Apples are not in season.
DB<3> print $href->{Fruit}->{Apples}->{Red}

DB<4> print join "\n", keys %{$href->{Fruit}}
Bananas
Apples

Cuando un valor undef es de-referenciado siendo usado como lvalue se autovivifica:

>perl -Mstrict -wle 'my $r; my @x; @$r=@x; print "$r\n"' 
ARRAY(0x225280)
Es en cierto modo razonable, ya que si está en el lado izquierdo es que se le quiere definir. Esto no ocurre si se usa como rvalue:

>perl -Mstrict -wle 'my $r; my @x; @x=@$r; print "$r\n"' 
Can't use an undefined value as an ARRAY reference at -e line 1.

Distinguir cuando una expresión esta siendo usada como rvalue o lvalue puede ser sutíl. Por ejemplo:

  DB<1> x use strict; my $r = undef; my @x = map{ $_ } @{ $r }
  empty array



Subsecciones
Casiano Rodríguez León
2009-10-04