elLunes has asked for the wisdom of the Perl Monks concerning the following question:

Running the following code outlines my problem best. In version 1 I try to add a sub reference to another sub reference within the same hash. The result is something like $VAR1->{'1'}{'test2'}. But what I expect can be seen in the output of version 2. Can someone give me a hint what's to do to get version 1 running correctly? Cheers elLunes
use Data::Dumper; # VERSION 1 my $ref_1; $ref_1->{'1'}->{'test1'}->{'key1'} = '1'; $ref_1->{'1'}->{'test1'}->{'key2'} = '2'; $ref_1->{'1'}->{'test1'}->{'key3'} = '3'; $ref_1->{'1'}->{'test2'}->{'key1'} = '4'; $ref_1->{'1'}->{'test2'}->{'key2'} = '5'; $ref_1->{'1'}->{'test2'}->{'key3'} = '6'; $ref_1->{'2'}->{'test1'}->{'key1'} = '1'; $ref_1->{'2'}->{'test1'}->{'key2'} = '2'; $ref_1->{'2'}->{'test1'}->{'key3'} = '3'; $ref_1->{'2'}->{'test2'}->{'key1'} = '4'; $ref_1->{'2'}->{'test2'}->{'key2'} = '5'; $ref_1->{'2'}->{'test2'}->{'key3'} = '6'; foreach my $b1 (keys %{$ref_1->{'1'}}) { if(exists $ref_1->{'2'}->{$b1}) { $ref_1->{'2'}->{$b1}->{'1'} = $ref_1->{'1'}->{$b1}; } } print Dumper $ref_1; # VERSION 2 my $ref_2; $ref_2a->{'1'}->{'test1'}->{'key1'} = '1'; $ref_2a->{'1'}->{'test1'}->{'key2'} = '2'; $ref_2a->{'1'}->{'test1'}->{'key3'} = '3'; $ref_2a->{'1'}->{'test2'}->{'key1'} = '4'; $ref_2a->{'1'}->{'test2'}->{'key2'} = '5'; $ref_2a->{'1'}->{'test2'}->{'key3'} = '6'; $ref_2b->{'2'}->{'test1'}->{'key1'} = '1'; $ref_2b->{'2'}->{'test1'}->{'key2'} = '2'; $ref_2b->{'2'}->{'test1'}->{'key3'} = '3'; $ref_2b->{'2'}->{'test2'}->{'key1'} = '4'; $ref_2b->{'2'}->{'test2'}->{'key2'} = '5'; $ref_2b->{'2'}->{'test2'}->{'key3'} = '6'; foreach my $b1 (keys %{$ref_2a->{'1'}}) { if(exists $ref_2b->{'2'}->{$b1}) { $ref_2b->{'2'}->{$b1}->{'1'} = $ref_2a->{'1'}->{$b1}; } } print Dumper $ref_2b;

Replies are listed 'Best First'.
Re: Hash reference Problem
by almut (Canon) on Dec 27, 2007 at 15:03 UTC
    The result is something like $VAR1->{'1'}{'test2'}.

    That's just due to the way Data::Dumper has to represent the data. In order to allow for the feature to be able to recreate the original data structure by eval-ing Data::Dumper's output, it cannot repeatedly expand substructures, because in that case you'd get a new instance of the structure (hash, array,...), instead of a reference to the existing structure.

    Try print Dumper $ref_2a, $ref_2b; in VERSION 2, and you'll see that it now also shows

    $VAR2 = { '2' => { 'test1' => { '1' => $VAR1->{'1'}{'test1'}, ...

    instead of the expanded style you got before

    $VAR1 = { '2' => { 'test1' => { '1' => { 'key2' => '2', 'key1' => '1', 'key3' => '3' }, ...

    That's because now it has already encountered (and displayed (or created upon eval-ing ...)) the structure referenced by $VAR1->{'1'}{'test1'}.

Re: Hash reference Problem
by gamache (Friar) on Dec 27, 2007 at 15:01 UTC
    It looks like in the first case, you end up storing a reference to a piece of an existing hash in $ref_1->{2}{testX}{1}, and in the second case you get the actual bits of hash rather than a reference to another place in which they exist.

    Sounds like you want use Storable qw(dclone), which performs a "deep clone" of nested data structures:

    use Storable qw(dclone); foreach my $b1 (keys %{$ref_1->{'1'}}) { if(exists $ref_1->{'2'}->{$b1}) { $ref_1->{'2'}->{$b1}->{'1'} = dclone $ref_1->{'1'}->{$b1}; } } print Dumper $ref_1;

    Side note: In Perl, pointer syntax (->) is optional after the first one; that is, $ref_1->{1}->{test1}->{1} is equivalent to $ref_1->{1}{test1}{1}.

Re: Hash reference Problem
by glide (Pilgrim) on Dec 27, 2007 at 15:03 UTC
    This output
    '2' => { 'test1' => { '1' => $VAR1->{'1'}{'test1'},
    it's just a more compact way of showing the structure

    try this

    use Data::Dumper; # VERSION 1 my $ref_1; $ref_1->{'1'}->{'test1'}->{'key1'} = '1'; $ref_1->{'1'}->{'test1'}->{'key2'} = '2'; $ref_1->{'1'}->{'test1'}->{'key3'} = '3'; $ref_1->{'1'}->{'test2'}->{'key1'} = '4'; $ref_1->{'1'}->{'test2'}->{'key2'} = '5'; $ref_1->{'1'}->{'test2'}->{'key3'} = '6'; $ref_1->{'2'}->{'test1'}->{'key1'} = '1'; $ref_1->{'2'}->{'test1'}->{'key2'} = '2'; $ref_1->{'2'}->{'test1'}->{'key3'} = '3'; $ref_1->{'2'}->{'test2'}->{'key1'} = '4'; $ref_1->{'2'}->{'test2'}->{'key2'} = '5'; $ref_1->{'2'}->{'test2'}->{'key3'} = '6'; foreach my $b1 (keys %{$ref_1->{'1'}}) { if(exists $ref_1->{'2'}->{$b1}) { $ref_1->{'2'}->{$b1}->{'1'} = $ref_1->{'1'}->{$b1}; } } $Data::Dumper::Deepcopy=1; print Dumper $ref_1;
Re: Hash reference Problem
by apl (Monsignor) on Dec 27, 2007 at 14:50 UTC
    First, you should replace my $ref_2; with my $ref_2a; my $ref_2b;

    Could you state, explicitly, what your question is?
Re: Hash reference Problem
by elLunes (Initiate) on Dec 28, 2007 at 09:57 UTC
    Hi everybody! Thanks a lot for your help!