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

I build a hash and then, I create an array of this hash and want to modify the value of one key of the hash. Although I assign the array to the built hash, it just gets the first key and value:

perl test.pl curr CD 0 AB 1 currhash CD 0 AB 0

and if I pass the reference of the hash, the hash gets modified which is not desired perl test.pl curr AB 1 currhash CD 0 AB 0

What's wrong? see the attached program Thanks carol

#!/usr/bin/perl sub parseFiles{ @currArr=(); push @currArr,'+1'; push @currArr,'u'; push @currArr,%currHash; # push @currArr,%currHash; in the first c +ase $curr{"my"}=[@currArr]; $curr{"my"}->[2]{"AB"}++; #print scalar(keys %{$curr{"my"}->[2]}), "\n"; #print $curr{"my"}->[0], " ", $curr{"my"}->[1], "\n"; print "curr\n"; foreach (keys %{$curr{"my"}->[2]}){ print $_, " ", $curr{"my"}->[2]{$_}, " "; } print "\n"; print "currhash\n"; foreach (keys %currHash){ print $_, " ", $currHash{$_}, " "; } print "\n"; } sub storeHash{ $currHash{"AB"}=$currHash{"CD"}= 0; } sub main{ storeHash(); parseFiles(); } main();

Replies are listed 'Best First'.
Re: array of hash
by choroba (Cardinal) on May 27, 2014 at 09:35 UTC

      perhaps I didn't fully understand your comment but i changed my program based on use strict. I still have problem

      If I don't use the hash ref, I get this error Can't use string ("CD") as a HASH ref while "strict refs" in use at ./test.pl line 15.

      and if i use hash ref, I don't get any value for the key CD Don't know why?! curr CD AB 1 currhash CD AB 1

      The desired output is curr CD 0 AB 1 currhash CD 0 AB 0

      #!/usr/bin/perl use strict; sub parseFiles{ my @currArr=(); my %curr; my %tmp = $_[0]; push @currArr,'+1'; push @currArr,'u'; push @currArr,%tmp; # push @currArr,%currHash; in the first case $curr{"my"}=[@currArr]; $curr{"my"}->[2]{"AB"}++; #print scalar(keys %{$curr{"my"}->[2]}), "\n"; #print $curr{"my"}->[0], " ", $curr{"my"}->[1], "\n"; print "curr\n"; foreach (keys %{$curr{"my"}->[2]}){ print $_, " ", $curr{"my"}->[2]{$_}, " "; } print "\n"; print "currhash\n"; foreach (keys %tmp){ print $_, " ", $tmp{$_}, " "; } print "\n"; } sub storeHash{ my %currHash; $currHash{"AB"}=$currHash{"CD"}= 0; return %currHash; } sub main{ my %currHash; %currHash=storeHash(); parseFiles(%currHash); } main();
        Can't use string ("CD") as a HASH ref while "strict refs" in use

        Yes, that's the point you perhaps didn't fully understand. $cur{my}[2] is "CD", you can't dereference it as a hash under strict. Without strict, it's understood as symbol reference and the hash %CD is used, as I demonstrated in my original reply.

        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Cont.

      by the way, despite use strict, the value of %currHash is modified. So the problem is still there.

Re: array of hash
by Lotus1 (Vicar) on May 27, 2014 at 14:59 UTC
    I build a hash and then, I create an array of this hash...
    push @currArr,%currHash;

    As choroba pointed out you are not building an array of hashes here. An array of hashes is actually an array of hash references. The Perl Data Structures Cookbook shows a few different ways to create arrays of hashes. However, from your example code it isn't obvious that an array of hashes is what you need.

    $curr{"my"}->[2]{"AB"}++;

    This looks like you're trying to use a hash of arrays of hashes. Can you describe the data structure you need or the problem you are trying to solve? Maybe check out some tutorials for perl data structures.

      Choroba's solution, push @currArr,{%currHash}; works like a charm.

      Many thanks