adding an element to AoH
Anonymous Monk
created: 2006-01-05 09:22:35
Fellow Monks,

I'm trying to add an element, unsuccessfully:
$AoH[0]->{heading}->[3]->{item => 'eee'};
Can anyone tell me how to do this. Here's my snippet:
#!/usr/bin/perl

use warnings;
use strict;

my @AoH = ({
              title   => 'aaa',
              heading => [
                          {item  => 'bbb'},
                          {item  => 'ccc'},
                          {item  => 'ddd'},
            ]});

$AoH[0]->{heading}->[3]->{item  => 'eee'};

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};
Thanks a lot,
Jonathan
Re: adding an element to AoH
created: 2006-01-05 09:27:55

If i understood your question correctly, here is the solution for that.

change
$AoH[0]->{heading}->[3]->{item  => 'eee'};
into
$AoH[0]->{heading}->[3]->{item} = 'eee';

Prasad

Re: adding an element to AoH
created: 2006-01-05 10:02:08
[prasadbabu] is right about how to add an element to the hash. You also don't need to type the dereferencing arrows between each level.

$AoH[0]{heading}[3]{item} = 'eee';

...will work fine.

Re: adding an element to AoH
created: 2006-01-05 10:12:12
Actually - [prasadbabu]'s solution does not do what the OP wants.
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.

Re^2: adding an element to AoH
created: 2006-01-05 10:23:14

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
created: 2006-01-05 10:29:38

[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

Re^2: adding an element to AoH
created: 2006-01-05 12:45:36

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).

Re^3: adding an element to AoH
created: 2006-01-05 15:03:56
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' };

perlmonks.org content © perlmonks.org and Anonymous Monk, friedo, jhourcle, NetWallah, prasadbabu, Tanktalus, tirwhan

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03