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

Hi all, I have a PERL script in which I do the following: -call a subroutine to do some file initialization and stuff - return -initialize a hash (%hashname = (); ) -call a subroutine, passing a reference to the hash. In the subroutine I parse a bunch of data and eventually write to the hash thusly: $$hashname{$key1}{$key2}{$key3}{$key4} = $value; - call a second subroutine, passing a reference to the hash to it. Here's where the trouble starts..... Here's my subroutine:
sub GEN_HTML { + # generate HTML for form $mp3hash = shift; + # hash - parsed xml itunes data #print Dumper(\%{$mp3hash}); foreach $player (sort keys %{$mp3hash}) { foreach $collection (sort keys %{$mp3hash{$player}}) { print "DEBUG: the player is [$player] the collection is [$collection]\ +n"; foreach $thetrack ( sort keys %{$mp3hash{$player}{$collect +ion}}) { foreach $bute ( sort keys %{$mp3hash{$player}{$collect +ion}{$track_name}}) { print "$player - $collection - $thetrack - $mp3has +h{$player}{$collection}{$track_name}{$bute}\n"; } } } } return; }
If I uncomment the Dumper line, I get the expected data structure and data. If I put a print statement after the first foreach and print $player, I get the data I expect, however, I cannot get any of the data from the inner foreach loops to print. I'm pretty sure I just haven't figure out how to properly de-reference the keys in the inner loops, but I can't seem to figure out how to do this.... Oh, and if I put these loops up in main, everything works fine..... Any help? Thanks, bigtiny

Replies are listed 'Best First'.
Re: Cannot dereference hash in subroutine....
by davorg (Chancellor) on Jul 18, 2005 at 15:10 UTC

    I think we'd need to see either the code where you build the hash or the output of the Data::Dumper call in order to know what your data structure _really_ is. It obviously isn't what you think it is (or you'd be getting the right results!) so I think you may be misreading the output from Data::Dumper.

    It's just a guess, but I wouldn't be surprised if you have one more or one less level of references than you think you do.

    Update: Looking at your code again, it looks like I'm right. You have (for example) $mp3hash{$player} where you should probably have $mp3hash->{$player}.

    This is a good example of where use strict is useful as it would have told you that you are trying to access a variable that does exist (the hash %mp4hash).

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      I appreciate the answer, however, if the data is not structured as I think it is, why do these statements work when issued against the hash in main (and they do....) ? bigtiny

        At a guess, because outside of this subroutine you are accessing the hash, whereas in this subroutine you are using a reference to the hash.

        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

Re: Cannot dereference hash in subroutine....
by ikegami (Patriarch) on Jul 18, 2005 at 15:33 UTC

    Change
    %{$mp3hash{$player}...}
    to
    %{$mp3hash->{$player}...}
    or to
    %{$$mp3hash{$player}...}
    because you want to use $mp3hash (a reference to a hash), but you're using %mp3hash (which doesn't exist).

    use strict would have found this error. use strict would also point out that all your variables are global (which is asking for trouble).

    By the way,
    print Dumper(\%{$mp3hash});
    is the same as
    print Dumper($mp3hash);

Re: Cannot dereference hash in subroutine....
by artist (Parson) on Jul 18, 2005 at 15:16 UTC
    Don't know much about your error, but you can try mp3. That may be able to eliminate some errors before happening.
    --Artist
Re: Cannot dereference hash in subroutine....
by ysth (Canon) on Jul 19, 2005 at 06:35 UTC
    sub GEN_HTML { + # generate HTML for form $mp3hash = shift;
    That $mp3hash is a global variable, a strange thing to put a sub parameter in. Did you mean my $mp3hash = shift;?