how to use perl references correctly

perl, reference

Solution

It's not that `$h{'2'}` is a reference to `$h{'1'}`, but that both are references to the same array, namely `@a`. What you probably want is:

for my $i ( 1 .. 2 ) {
    $h{"$i"} = $a[$i - 1];
}

which is equivalent to this:

$h{'1'} = $a[0];   # i.e., $a1_ref
$h{'2'} = $a[1];   # i.e., $a2_ref

which makes `$h{'1'}` a reference to `@a1` and `$h{'2'}` a reference to `@a2`.

Incidentally, you might find it helpful to use the notations `[ ... ]` and `{ ... }` to create references to anonymous arrays and hashes (respectively). Since you never use `@a1` and `@a2` except via `$a1_ref` and `$a2_ref`, you might as well create the latter directly:

my $a1_ref = [ 'a1', 1, 1, 1 ];   # reference to a new array (no name needed)
my $a2_ref = [ 'a2', 2, 2, 2 ];   # ditto

Edited for updated question: To copy an array, you can write:

my @orig = (1, 2, 3);
my @new = @orig;

or:

my $orig_ref = [1, 2, 3];
my $new_ref = [@$orig_ref]; # arrayref -> array -> list -> array -> arrayref

In your case, if I understand you correctly, you need to perform a slightly "deep" copy: you don't just want two arrays with the same elements, you want two arrays whose elements are references to distinct arrays with the same elements. There's no built-in Perl way to do that, but you can write a loop, or use the `map` function:

my @orig = ([1, 2, 3], [4, 5, 6]);
my @new = map [@$_], @orig;

So:

for my $i ( 1 .. 2 ) {
    $h{"$i"} = [map [@$_], @a];
}

Problem

I have a very noob-ish question here regarding refs, though still confounding to me at the very least... In the code example below, i'm trying to create a hash of arrays: ``` #!/usr/bin/perl use strict; use warnings; use 5.010; use Data::Dumper; $Data::Dumper::Sortkeys = 1; $Data::Dumper::Terse = 1; $Data::Dumper::Quotekeys = 0; my @a1 = ( 'a1', 1, 1, 1 ); my @a2 = ( 'a2', 2, 2, 2 ); my $a1_ref = \@a1; my $a2_ref = \@a2; my @a = ( $a1_ref, $a2_ref ); my %h = (); for my $i ( 1 .. 2 ) { $h{"$i"} = \@a; } say Dumper \%h; ``` The Dumper output is ``` { '1' => [ [ 'a1', 1, 1, 1 ], [ 'a2', 2, 2, 2 ] ], '2' => $VAR1->{'1'} } ``` The question here is: why is $h{'2'} a reference to $h{'1'}? I'm trying to create a hash %h with identical key-values made of the @a array-of-arrays. I want each key-value of the hash to have it's own AoA based on @a, but i'm getting references to $h{'1'} instead. What am i doing wrong?? The Dumper output i'm trying to achive is: ``` { '1' => [ [ 'a1', 1, 1, 1 ], [ 'a2', 2, 2, 2 ] ], '2' => [ [ 'a1', 1, 1, 1 ], [ 'a2', 2, 2, 2 ] ] } ``` Any help appreciated. thanks in advance! -dan

Original source

Related problems