Perl: Assigning an array to a hash
Solution 1
The part you're missing is that @a = [1,2,3]
doesn't make an array with 3 elements. It makes an array with one element which is an arrayref.
You meant @a = (1,2,3)
.
To assign that array to a hash element, you'd use either $b{"x"} = [@a]
or $b{"x"} = \@a
, depending on what you're trying to do. [@a]
makes a new arrayref containing a copy of the current contents of @a
. If the contents of @a
change after that, it has no effect on $b{x}
.
On the other hand, \@a
gives you a reference to @a
itself. If you then change the contents of @a
, that will be visible in $b{x}
(and vice versa).
Solution 2
You need to read the perlref documentation that talks about references.
There is a difference in how your arrays are stored:
# this is an array in an array variable
@a = (1, 2, 3);
Verses storing a reference to an array:
# this is an array in a scalar variable stored as a reference to the previous array:
$b = \@a;
Functionally that works like a pointer. Thus you can also store this reference in a hash:
$x{'something'} = \@a;
This all works just fine. What you haven't realized is that []s create references to an array, which you can't store in an array variable. You must store it in a scalar. Thus this instead:
$c = [1, 2, 3];
$x{'else'} = $c;
will work.
And accessing and modifying the array before you do the second assignment can be done using:
$c->[3] = '4';
or by using it in array form dereferencing it first
push @$c, 5;
Comments
-
Walt Stoneburner over 3 years
This syntax works:
$b{"x"} = [1,2,3]; pp %b; # Displays ("x", [1, 2, 3])
But I need to be able to dynamically create the array's contents and assign it later. This does not work; help, what's the obvious part I'm missing?
@a = [1,2,3]; $b{"x"} = @a; pp %b; # Shows up as ("x", 1) ... not what I want or expected.
Tried these variations, too.
$b{"x"} = [@a]; # ("x", [[1, 2, 3]]) ...close $b{"x"} = \@a; # ("x", [[1, 2, 3]]) $b{"x"} = [\@a]; # ("x", [[[1, 2, 3]]]) $b{"x"} = %a; # ("x", 0) $b{"x"} = $a; # ("x", undef) $b{"x"} = [$a]; # ("x", [undef]) $b{"x"} = @{@a}; # ("x", 0)
And, ideally, I'd like to be able to get the array back out later as an array.