in reply to adding an element to AoH

Actually - prasadbabu's solution does not do what the OP wants.
Update Thanks to tirwhan, Tanktalus, and prasadbabu for setting the record straight on this one. My interpretation of the OP's intent was different than prasadbabu's.

Here is working code for what he wants to do:

$AoH[0]->{heading}->[3] = {item => 'eee'};
Note the location of the "=" sign.

My preference would be to avoid the C-style absolute indexing, and use:

push @{$AoH[0]->{heading}} , {item => 'eee'};

     You're just jealous cause the voices are only talking to me.

     No trees were killed in the sending of this message.    However, a large number of electrons were terribly inconvenienced.

Replies are listed 'Best First'.
Re^2: adding an element to AoH
by Tanktalus (Canon) on Jan 05, 2006 at 17:45 UTC

    Ok, a couple people have responded saying that your version and prasadbabu's solution are exactly the same. They are both right and wrong.

    prasadbabu's solution works due to autovivication. As that is a fully documented feature of perl, this should not be taken as a vilification - it's taking advantage of exactly what perl says it will do, and makes it a very perlish solution IMO.

    What prasadbabu's solution does not do, however, is fully reinitialise the hashref. If $AoH[0]{heading}[3] doesn't already exist, both methods work just the same. If it does exist, however, the two solutions are widely divergent. I can't even count the number of times I've used your first solution, NetWallah, when I was supposed to use prasadbabu's solution - when I overwrote a structure intending merely to update it. Thus, in my experience, prasadbabu's solution is more often the correct solution.

    That said, I often use your latter solution - and find that when I do so, I almost never use it incorrectly. I often claim that code that solves the problem in the domain of the problem rather than the solution is more often correct. This style of pushing into an array is, in my experience, very often exactly how the problem is stated, and since the code matches the problem, it's rarely wrong. It's also hard to get off-by-one errors and the like.

    So the question to the OP is: what is your real problem that you're trying to solve? The question seems obvious to me that it's a question in the domain of the solution rather than the domain of the problem. If you're trying to add a new hash to the end of an array, then NetWallah's preferred solution is probably the right one. If you're merely trying to update a specific entry (creating it if it doesn't exist), then prasadbabu's solution is the right one. If you're trying to replace an entry in your array, then NetWallah's first snippet is the right one. I can't really tell which one is the right one - all I can do is point out what each solution's strength is, and it's up to you to decide which one best fits your problem (not solution).

      If you're trying to add a new hash to the end of an array, then NetWallah's preferred solution is probably the right one

      If you're always adding a new element to the array, I'd suggest a third solution, so you don't need to worry about the current size of the array:

      push @{ $AoH[0]{'heading'} }, { item => 'eee' };

      Update: Must stop skimming ... didn't see both code lines on NetWallah's response.

Re^2: adding an element to AoH
by tirwhan (Abbot) on Jan 05, 2006 at 15:23 UTC

    Umm, that does exactly the same thing:

    use Data::Dumper; use Test::More qw(no_plan); $AoH[0]->{heading}->[3]->{item} = 'eee'; print Dumper @AoH; $BoH[0]->{heading}->[3] = {item => 'eee'}; print Dumper @BoH; is_deeply(@AoH,@BoH,"They're the same");

    Output:

    $VAR1 = { 'heading' => [ undef, undef, undef, { 'item' => 'eee' } ] }; $VAR1 = { 'heading' => [ undef, undef, undef, { 'item' => 'eee' } ] }; ok 1 - They're the same 1..1

    A computer is a state machine. Threads are for people who can't program state machines. -- Alan Cox
Re^2: adding an element to AoH
by prasadbabu (Prior) on Jan 05, 2006 at 15:29 UTC

    NetWallah, I think there is no difference between your's and mine.

    #!/usr/bin/perl use strict; use Data::Dumper; my @AoH = ({ title => 'aaa', heading => [ {item => 'bbb'}, {item => 'ccc'}, {item => 'ddd'}, ]}); #$AoH[0]->{heading}->[3] = {item => 'eee'}; #your's $AoH[0]->{heading}->[3]->{item} = 'eee';#mine #print $AoH[0]->{title}; #print $AoH[0]->{heading}->[0]->{item}; #print $AoH[0]->{heading}->[1]->{item}; #print $AoH[0]->{heading}->[2]->{item}; #print $AoH[0]->{heading}->[3]->{item}; print Dumper @AoH;

    your output:

    $VAR1 = { 'heading' => [ { 'item' => 'bbb' }, { 'item' => 'ccc' }, { 'item' => 'ddd' }, { 'item' => 'eee' } ], 'title' => 'aaa' };

    my output:

    $VAR1 = { 'heading' => [ { 'item' => 'bbb' }, { 'item' => 'ccc' }, { 'item' => 'ddd' }, { 'item' => 'eee' } ], 'title' => 'aaa' };

    Prasad