views:

163

answers:

3

Is it possible to push to an array reference in Perl? Googling has suggested I deference the array first, but this doesn't really work. It pushes to the deferenced array, not the referenced array.

For example,

my @a = ();

my $a_ref = [@a];

push(@$a_ref,"hello");

print $a[0];

@a will not be updated and this code will fail because the array is still empty

(I'm still learning Perl references, so this might be an incredibly simple question. Sorry if so)

+1  A: 

$a is not $a_ref, ($a is the first comparison variable given to a sort{}, and $a[0] is the 0th element of the @a array).Never use $a, or $b outside of a custom sort subroutine, and the @a and @b array should probably be avoided to too (there are plenty of better choices)...

What you're doing is assigning to $a_ref, an anonymous array, and then pushing onto it "hello", but printing out the first element of the @a array.

Evan Carroll
+12  A: 

It might help to think in terms of memory addresses instead of variable names.

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.

The string went into a different memory location.

Instead, point the $a_ref variable to the memory location of list @a. push affects memory location 123. Since @a also refers to memory location 123, its value also changes.

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.
Robert Wohlfarth
Nice explanation. But you could use the terminology that at least some deep level of perl uses and point out that `[...]` is a *constructor* expression.
Axeman
+1  A: 

Yes its possible. This works for me.

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

As has been mentioned, $aref = [@a] will copy and not create reference to a

neal aise