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

Hey everyone, I have a hash here which looks like this
foreach $line (@list) { | | | ++$count{$sale_name => $fy} # fy = Fiscal Year }
when I try to print the output with a foreach like so
foreach my $listing (sort keys %count) { print “$count{$listing}”; }
It prints this weird “cube” in the middle:
SALE"*"2002 I know this is the “comma arrow (=>)” operator that’s the culprit, but you see I still need some sort of relationship between the $sale_name and $fy in the first foreach. All I want to know is how to avoid this issue. Any suggestions will be great...

Replies are listed 'Best First'.
Re: Relationships between hash Data
by Fletch (Bishop) on Nov 07, 2001 at 00:12 UTC

    You're confuzzled and have accidentally stumbled around the perl4 compatibility feature for making multilevel hashes from the time before references were available. Since `=>' is really just a fancy comma, what you're really doing is:

    ++$count{$sale_name, $fy};

    What this is doing behind the scenes is implicitly joining the multiple values together seperated by $; (which is "\034" by default, which very well show up as a strange glyph depending on your font; see perldoc perlvar for more details). What you really want is probably a multi-level datastructure such as a hash of hashes. See perldoc perlreftut, perldoc perlref, and perldoc perldsc for more details.

Re: Relationships between hash Data
by demerphq (Chancellor) on Nov 07, 2001 at 00:55 UTC
    It took me a while but I tracked down the cause of your ugly symbol (FS or ^\) I dont think to many people use this one but from perldoc perlvar:

    _______________________________________________________
    $SUBSCRIPT_SEPARATOR
    $SUBSEP
    $;

    The subscript separator for multidimensional array emulation. If you refer to a hash element as
    $foo{$a,$b,$c}
    it really means
    $foo{join($;, $a, $b, $c)}
    But don't put
    @foo{$a,$b,$c}      # a slice--note the @
    which means
    ($foo{$a},$foo{$b},$foo{$c})
    Default is ``\034'', the same as SUBSEP in awk. If your keys contain binary data there might not be any safe value for $;. (Mnemonic: comma (the syntactic subscript separator) is a semi-semicolon. Yeah, I know, it's pretty lame, but $, is already taken for something more important.)

    Consider using ``real'' multidimensional arrays as described in the perllol manpage.
    _______________________________________________________

    So you could set $; to something that isnt so 'ugly' or more intelligently use a two level hash, often called a HOH like so:

    use Data::Dumper; my (%Sales,%Years); #.... ++$Sales{$sale_name}->{$fy}; # fy = Fiscal Year # and/or ++$Years{$fy}->{$sale_name}; # fy = Fiscal Year #.... print Dumper(\%Sales,\%Years); # _very_ usefull tool. # Less useful, but more obvious than messing with $; ++$count->{"$sale_name : $fy"}; # fy = Fiscal Year
    Reversing the relationship or using both can also be useful. Of course putting them together into titles involves an extra loop but ultimately I'd say this is the way to go.

    HTH

    Yves / DeMerphq
    --
    Have you registered your Name Space?