Look in perlref under "symbolic references" for the official scoop, but here's a brief tutorial.

The values in a hash are all scalars. You cannot store a hash in a hash. $h{key} is always a simple scalar value. A reference, however, is also a scalar, so you can store a reference to a hash in a hash.

When you say $h{key}{subkey}, the $h{key} in that expression has to be a reference to a hash. If it turns out that it's a reference to an array, for example, you'll get an error.

When you set $b{$bid} = 'foo' and then say $b{$bid}{'blah'} = 'hahaha', that treats $b{$bid} as a reference. It's a reference to a hash named %foo because $b{$bid} has the value "foo".

So, when you went from using "1" to using "ok", you went from putting everything in %1 to putting everything in %ok. You have the same problem by a different name.

If, as you write in Re^7: Why is my code assigning the last-retrieved value to all elements in my hash?, you set each value to a different string, it "works" because those "references" all go to different hashes.

$b{$bid} = "The Diamond Age"; # $b{$bid}{foo} uses %{"The Diamond Age"} $b{$bid} = "Snow Crash"; # $b{$bid}{foo} uses %{"Snow Crash"} $b{$bid} = "b"; # $b{$bid}{foo} pollutes %b directly!

What I've written about mostly so far is just symbolic references. There's another kind, hard references, that don't go around mucking up other variables, because they don't refer to other variables.

$b{$bid} = {};

That creates a hard reference to an anonymous hash. You can then use $b{$bid} to refer to the (anonymous) hash, and it won't destroy other variables willy nilly.

I hope this clears up what's going on with your code.

I've suggested several times that you use strict. I suggest this because it prevents you from using symbolic references. Any attempt to use a string as a reference will cause a fatal error. It also forces you to use my to declare your variables (or refer to them explicitly as package variables), which is another good thing.

There's one other misconception you seem to have that I'd like to clear up. You can't have a $b{foo}{bar} and have $b{foo} set to some unrelated value (such as 1). If there is a $b{foo}{bar}, then $b{foo} must somehow be a reference to a hash where you access ->{bar}. In your original code, that "reference" was "1", treated as a symbolic reference to %1. In the code I suggested, it's a hard reference to an anonymous hash that gets printed as 'HASH(0x8529f88)'.


In reply to Re^7: Why is my code assigning the last-retrieved value to all elements in my hash? by kyle
in thread Why is my code assigning the last-retrieved value to all elements in my hash? by punch_card_don

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.