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

I've been trying to figure out what causes the strange output I receive from the following code but to no avail. I suppose I'm doing something wrong but I'd appreciate a brotherly hint.
#!/usr/bin/perl -- %griph=('c' => @c_griph, 'b' => @b_griph, 'f' => @f_griph, 'o' => @o_griph, 'r' => @r_griph, 'm' => @m_griph, 'y' => @y_griph, 'g' => @g_griph, 'p' => @p_griph, 'w' => @w_griph); print "c = ",$griph{'c'},"\n"; print "b = ",$griph{'b'},"\n"; print "f = ",$griph{'f'},"\n"; print "o = ",$griph{'o'},"\n"; print "r = ",$griph{'r'},"\n"; print "m = ",$griph{'m'},"\n"; print "y = ",$griph{'y'},"\n"; print "g = ",$griph{'g'},"\n"; print "p = ",$griph{'p'},"\n"; print "w = ",$griph{'w'},"\n";
Output:
c = b b = f = o o = r = m m = y = g g = p = w w =

Replies are listed 'Best First'.
Re: Multidimensional hashes
by ikegami (Patriarch) on Nov 02, 2004 at 22:30 UTC

    You can't actually put anything except scalars into a hash or an array, so you have to put a reference to the array into the hash.

    @b_griph = ('foo', 'bar'); %griph=('c' => \@c_griph, 'b' => \@b_griph, 'f' => \@f_griph, 'o' => \@o_griph, 'r' => \@r_griph, 'm' => \@m_griph, 'y' => \@y_griph, 'g' => \@g_griph, 'p' => \@p_griph, 'w' => \@w_griph); print "c = ",@{$griph{'c'}},"\n"; print "b = ",@{$griph{'b'}},"\n"; print "f = ",@{$griph{'f'}},"\n"; print "o = ",@{$griph{'o'}},"\n"; print "r = ",@{$griph{'r'}},"\n"; print "m = ",@{$griph{'m'}},"\n"; print "y = ",@{$griph{'y'}},"\n"; print "g = ",@{$griph{'g'}},"\n"; print "p = ",@{$griph{'p'}},"\n"; print "w = ",@{$griph{'w'}},"\n"; __END__ output ====== c = b = foobar f = o = r = m = y = g = p = w =

    by the way, the print code can be simplified to:

    foreach $key (keys(%griph)) { print("$key = @{$griph{$key}}\n"); }

    Data::Dumper is very useful for debugging:

    use Data::Dumper; print(Dumper(\%griph));
Re: Multidimensional hashes
by jeffa (Bishop) on Nov 02, 2004 at 22:32 UTC

    You have to reference the arrays first:

    %griph=('c' => \@c_griph, 'b' => \@b_griph, 'f' => \@f_griph, 'o' => \@o_griph, 'r' => \@r_griph, 'm' => \@m_griph, 'y' => \@y_griph, 'g' => \@g_griph, 'p' => \@p_griph, 'w' => \@w_griph);
    Because if you don't, then every array is "flattened" into one list, and the key value pairs are determined afterwards. Run this code and observe:
    use Data::Dumper; my @array = 1 ..5; my %hash = (a => @array, b => 'foo'); print Dumper \%hash;

    So, now that you have referenced the arrays, you have to de-reference them in order to use them, like so:

    print "$_\n" for @{ $griph{c} };

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: Multidimensional hashes
by BrowserUk (Patriarch) on Nov 02, 2004 at 22:32 UTC

    If the array @c_cgraph is empty, then that part of the list is equivalent to:  %griph = ( c, (), b, (), ...

    which is equivalent to  %griph = ( c, b, ...

    hence your results.

    You almost certainly want

    %griph=('c' => \@c_griph, 'b' => \@b_griph, ...

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: Multidimensional hashes
by pg (Canon) on Nov 02, 2004 at 22:33 UTC

    You want array ref, not array as hash values.

    Also use Data::Dumper, so you don't need to code to dump the hash.

      Now I get it! Thanks guys!
Re: Multidimensional hashes
by dimar (Curate) on Nov 03, 2004 at 18:35 UTC

    ... and since you are using *array references* instead of arrays, you dont really need @c_griph, @b_griph, (and the rest) to begin with. You can save yourself a lot of keystrokes, potential bugs, (and hassle if you later need to add @z_griph, @zzz_griph and so forth) if you just use ...

    @griph_keys = qw( c b f o r m y g p w); @griph{@griph_keys} = (); $griph{f} = ['foo','faa']; $griph{c} = ['coo','caa']; $griph{b} = ['bee','baa']; $griph{r} = ['ree','raa']; use Data::Dumper; print(Dumper(\%griph));

    ... hope that make sense.