2010-06-16 6 views
23

¿Es posible push a una matriz de referencia en Perl? Google ha sugerido que deferencia la matriz primero, pero esto realmente no funciona. Empuja a la matriz de referencia, no a la matriz a la que se hace referencia.Presione para matriz de referencia

Por ejemplo,

my @a =(); 

my $a_ref = [@a]; 

push(@$a_ref,"hello"); 

print $a[0]; 

@a no se actualizará y este código fallará porque la matriz está vacía

(todavía estoy aprendiendo referencias Perl, por lo que este podría ser un increíblemente sencillo cuestión. lo siento si es así)

+9

'my $ a_ref = \ @a;' - ha creado una nueva matriz_referencias, con como primer elemento la matriz vacía -> entonces solo una matriz vacía. – Konerak

+5

'$ a_ref = [@a];' no hace referencia al original '@ a' - copia su contenido. – Ether

Respuesta

39

Puede ser útil pensar en términos de direcciones de memoria en lugar de nombres de variables.

my @a =();  # Set aside memory address 123 for a list. 

my $a_ref = [@a]; # Square brackets set aside memory address 456. 
        # @a COPIES the stuff from address 123 to 456. 

push(@$a_ref,"hello"); # Push a string into address 456. 

print $a[0]; # Print address 123. 

La secuencia entró en una ubicación de memoria diferente.

En su lugar, señale la variable $a_ref a la ubicación de memoria de la lista @a. push afecta a la ubicación de memoria 123. Dado que @a también se refiere a la ubicación de memoria 123, su valor también cambia.

my $a_ref = \@a;  # Point $a_ref to address 123. 
push(@$a_ref,"hello"); # Push a string into address 123. 
print $a[0];   # Print address 123. 
+6

Buena explicación. Pero podría usar la terminología que usa al menos un nivel profundo de perl y señalar que '[...]' es una expresión * constructor *. – Axeman

+0

Nota: No es necesario desreferenciar una referencia de matriz cuando la pasa a presionar (al menos con Perl moderno). Pero me imagino que Perl funciona de manera idéntica en ambos casos. – Jonathon

+0

¿La desactivación al usar push no crea una copia de la matriz? – Lukazoid

3

$a no es $a_ref, ($a es la primera variable de comparación dado a un sort{}, y $a[0] es el elemento de la matriz 0 ª @a) .Nunca utilizar $a o $b fuera de una subrutina de ordenación personalizada, y la matriz @a y @b probablemente se debe evitar a también (hay un montón de opciones mejores) ...

Lo que está haciendo es asignar a $a_ref, una matriz anónima, y ​​presionar sobre ella "hello", pero imprimiendo el primer elemento de la matriz @a.

1

Sí es posible. Esto funciona para mí

my @a =(); 
my $aref = \@a; # creates a reference to the array a 

push(@$aref, "somevalue"); # dereference $aref and push somevalue in it 

print $a[0]; # print the just pushed value, again @$aref[0] should also work 

Como se ha mencionado, $aref = [@a] copiará y no crear una referencia a

6

Usted puede empujar directamente en una matriz sin ref deferencing.

my $arrayRef = []; 
push $arrayRef, "one"; 
push $arrayRef, "two"; 
print @$arrayRef; 

Salidas

onetwo 

Documentación: http://perldoc.perl.org/functions/push.html

Comenzando con Perl 5.14, empuje puede tomar un EXPR escalar, que debe mantener una referencia a una matriz sin bendecir.

Pre 5.14 primero debe eliminar la referencia de la matriz.

push @$arrayRef, "item"; 

Editar: Annnnd empujando directamente a la matriz ref ya no se utiliza en un comunicado reciente Perl (5,24?).Teniendo esto en cuenta, sería más seguro eliminar siempre @ {$ arrayRef} antes de presionar para aumentar la compatibilidad de tu código.

+0

'push' en referencias realmente se eliminó por completo en Perl 5.24. – Xaerxess

Cuestiones relacionadas