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

I have another related issue here:
Building a Hash of arrays from a hash of arrays based on a list?
A full explanation is here.

This problem: I am trying to create a hash or list of references of dates that have a hash table of sedols mapped to the total amount of shares traded. I need for every unquie day associated with it a hash table of unique sedols mapped to the the total amount traded for each. .... I am getting:

Type of arg 1 to keys must be hash (not hash elem) at line 556

this is the line:

foreach $sedolelement (keys $tradedatehash{$tradedatemarker}) {
what is wrong?????
# ------ Build_tradedatehash_sedolandtotalsharesarray ----- sub Build_tradedatehash_sedolandtotalsharesarray($$$$) { #$j = shift; my $tradedate = shift; my $sedol = shift; my $shares = shift; $condition = ""; my $myfirstflag = shift; if ($myfirstflag eq "YES") { my $j = 0; } else { my $j = 1;} print "$tradedate $sedol $shares \n"; $count = 0; if ($j == 0) { $tradedatehash{$tradedate} = {$sedol => $shares}; foreach $tradedatemarker (%tradedatehash) { print "For the date: $tradedatemarker \n\tsedols \t total +shares\n\n"; foreach $sedolelement (keys $tradedatehash{$tradedatemarke +r}) { print "\t $sedolelement \t $_\n"; } print "\thave traded.\n"; } } else { #print "this is j $j\n"; foreach $tradedatemarker (${$tradedatehash{$tradedate}}) { if (exists $tradedatehash{%tradedate}) { print " yes yes yes $tradedatemarker\n!"; foreach $sedolelement (keys $tradedatehash{$tradedatem +arker}) { if (exists $sedol) { $tradedatehash{$trademarker}->{$sedol} += $sha +res; } else { $tradedatehash{$trademarker} = {$sedol => $sha +res}; }# } } else { $tradedatehash{$tradedate} = {$sedol => $shares}; } } foreach $tradedatemarker (${$tradedatehash{$tradedate}}) { print "For the date: $tradedatemarker \n\tsedols \t total +shares\n\n"; foreach $sedolelement (keys $tradedatehash{$tradedatemarke +r}) { print "\t $sedolelement \t $_\n"; } print "\thave traded.\n"; } } } # end sub Build_tradedatehash_sedolandtotalsharesarray

Replies are listed 'Best First'.
Re: Need help with hashes please!!!
by Masem (Monsignor) on Jan 27, 2002 at 05:12 UTC
    In your line:
    foreach $sedolelement (keys $tradedatehash{$tradedatemarker}) {
    the element $tradedatehash{$tradedatemarker} is going to be a hash reference, not a hash directly. This is because perl stores complex structures as references as opposed to direct storage (see perlref for more details). To convert this hashref to a hash variable that keys can use, you can 'dereference' it by surrounding the variable with %{ }, as in:
    foreach $sedolelement ( keys %{ $tradedatehash{ $tradedatemarker } } ) + { ... }
    (Similarly, array references are deref'ed with @{ }, if you need this)

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
    "I can see my house from here!"
    It's not what you know, but knowing how to find it if you don't know that's important

Re: Need help with hashes please!!!
by jonjacobmoon (Pilgrim) on Jan 27, 2002 at 05:14 UTC
    My first comment is this: I didn't read your previous post (the one you mention) for the same reason I almost skipped this one. You need to boil the code down to the offending sections or line and simplify your explainations.

    But, I will tell you that the proper syntax for a foreach loop with a hash is: foreach $key (keys %hash)

    if the hash is a reference then similiarily you do: foreach $key (keys %$hash)

    I am not sure what you are trying to do here, because I just don't have the time to decipher all of it, but I think you are trying to do the latter. So, the line needs to be:

    foreach $sedolelement (keys %$tradedatehash{$tradedatemarker}) {

    With the hash symbol in front of the scalar representing the hash. Hope that helps. I know that Ovid has a piece on proper style for postings but I could not locate it. Maybe someone else can.


    I admit it, I am Paco.