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

I have a HoAoH as in the following distilled example:

use strict; use warnings; use Data::Dumper; my %types = ( TYPE1 => [ { NAME => 'Joe', ID => '022'}, { NAME => 'Sue', ID => '088'}, { NAME => 'Tom', ID => '108'} ], TYPE2 => [ { NAME => 'Sue_B', ID => '089'}, { NAME => 'Sue_C', ID => '090'} ] ); splice @{$types{TYPE1}}, 1, 1, @{$types{TYPE2}}; print Dumper(\%types)

I am trying to replace the 'Sue' hash element in the array referenced by TYPE1 with both of the hash elements in the array referenced by TYPE2.

It seems to me that the splice should do the trick, but doesn't, producing the following output instead:

$VAR1 = { 'TYPE2' => [ { 'ID' => '089', 'NAME' => 'Sue_B' }, { 'ID' => '090', 'NAME' => 'Sue_C' } ], 'TYPE1' => [ { 'ID' => '022', 'NAME' => 'Joe' }, $VAR1->{'TYPE2'}[0], $VAR1->{'TYPE2'}[1], { 'ID' => '108', 'NAME' => 'Tom' } ] };

I am attempting to splice because I want to preserve the order of the elements in the arrays. Can anyone clue me in to what I am doing wrong and what a proper way of doing this would be?

Hanlon's Razor - "Never attribute to malice that which can be adequately explained by stupidity"

Replies are listed 'Best First'.
Re: Slicing a HoAoH
by edan (Curate) on Apr 28, 2004 at 15:24 UTC

    Your code is working fine. Perhaps what is throwing you off is the funny-looking output of Data::Dumper. The reason why you're getting those values in there is because you're working with references: the values that you spliced in there are hash-references that are found elsewhere in your structure. Data::Dumper is smart enough to know that, and just dumps it out 'self-referentially'.

    --
    edan (formerly known as 3dan)

Re: Slicing a HoAoH
by dreadpiratepeter (Priest) on Apr 28, 2004 at 15:25 UTC
    It did work. you are just misinterpreting the output from Dumper. After your operation is done, the rows you splice references to into TYPE1 appear in both lists. Dumper only prints them out once, printing a reference on successive occurrances of the reference.
    If what you really wanted was to copy the contencts of the hashref into TYPE1, then I would suggest you look at dclone in the Storable package.


    -pete
    "Worry is like a rocking chair. It gives you something to do, but it doesn't get you anywhere."
Re: Slicing a HoAoH
by rinceWind (Monsignor) on Apr 28, 2004 at 15:35 UTC
    When I run your example, I get
    $VAR1 = { 'TYPE1' => [ { 'ID' => '022', 'NAME' => 'Joe' }, { 'ID' => '089', 'NAME' => 'Sue_B' }, { 'ID' => '090', 'NAME' => 'Sue_C' }, { 'ID' => '108', 'NAME' => 'Tom' } ], 'TYPE2' => [ $VAR1->{'TYPE1'}[1], $VAR1->{'TYPE1'}[2] ] };
    What you are getting (as indeed I am) is a structure containing references to the same scalar. In this case Data::Dumper has DWIMed and used $VAR1->{'TYPE1'}[1] to point back to the same instance of the scalar.

    Hope this helps.

    --
    I'm Not Just Another Perl Hacker

Re: Slicing a HoAoH
by Roy Johnson (Monsignor) on Apr 28, 2004 at 15:37 UTC
    The array you're splicing into has a hash reference as the second element, and you're replacing it with two other references.

    It seems you want to copy the contents out before splicing in the references, so that you're referring to anonymous entries:

    splice @{$types{TYPE1}}, 1, 1, ({%{$types{'TYPE2'}[0]}},{%{$types{'TYP +E2'}[1]}});
    or
    splice @{$types{TYPE1}}, 1, 1, map {{%$_}} @{$types{'TYPE2'}};

    The PerlMonk tr/// Advocate
Re: Slicing a HoAoH
by artist (Parson) on Apr 28, 2004 at 15:38 UTC
    Your code works fine: Add following two lines to your code to see the results:
    print join "\t",(map { $_->{NAME}.':'.$_->{ID}} @{$types{TYPE1}}),"\n" +; print join "\t",(map { $_->{NAME}.':'.$_->{ID}} @{$types{TYPE2}}),"\n" +;
    It gives me:
    Joe:022	Sue_B:089	Sue_C:090	Tom:108	
    Sue_B:089	Sue_C:090	
    
Re: Slicing a HoAoH
by Art_XIV (Hermit) on Apr 28, 2004 at 15:38 UTC

    Thanks edan and dreadpiratepeter! The output was really throwing me.

    Update: Thanks everyone else, too. It was a real "D'oh!" moment. ;)

    Hanlon's Razor - "Never attribute to malice that which can be adequately explained by stupidity"
Re: Slicing a HoAoH
by eric256 (Parson) on Apr 28, 2004 at 15:35 UTC

    Isn't that correct? Or do you want it to copy the hash instead of the hashref? If you think about it $VAR1->{'TYPE2'}[0], IS the same hashreference as in TYPE2. The way data::Dumper displays it can be odd at times, especialy the first time you see it. If none of this is clear then it would help to see what you expected that to output.


    ___________
    Eric Hodges