Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

Hash to Scalar Assignment Oddity

by dsb (Chaplain)
on Jan 26, 2006 at 15:28 UTC ( #525734=perlquestion: print w/ replies, xml ) Need Help??
dsb has asked for the wisdom of the Perl Monks concerning the following question:

A coworker and I were trying to work out some of the code when tie'ing a hash to a Berkeley DB file. I noticed that one of the lines called for the return value from a tie() to be assigned to a scalar variable. So I tried assigning a regular old hash - not a reference to a hash - to a scalar. I didn't get what i expected.

I half expected the code to bomb. Instead the assignment evaluated and when I printed the contents of the scalar, I got a weird result. See the code.

%db = ( one => 1, two => 2, three => 3 ); print %db, "\n"; # prints 'three3one1two2' $db = %db; print $db, "\n"; # prints '3/8'
Anyone have an idea of what's going on here and why I get a fraction when I print the contents of $db?

This @ISA my( $cool ) %SIG

Replies are listed 'Best First'.
Re: Hash to Scalar Assignment Oddity
by philcrow (Priest) on Jan 26, 2006 at 15:34 UTC
    When you put a hash into scalar context, it gives information about the hash buckets (rarely useful).


Re: Hash to Scalar Assignment Oddity
by bunnyman (Hermit) on Jan 26, 2006 at 18:12 UTC

    This isn't odd. It's supposed to do that.

    If you evaluate a hash in scalar context, it returns false if the hash is empty. If there are any key/value pairs, it returns true; more precisely, the value returned is a string consisting of the number of used buckets and the number of allocated buckets, separated by a slash. This is pretty much useful only to find out whether Perl's internal hashing algorithm is performing poorly on your data set. For example, you stick 10,000 things in a hash, but evaluating %HASH in scalar context reveals "1/16" , which means only one out of sixteen buckets has been touched, and presumably contains all 10,000 of your items. This isn't supposed to happen.
    -- man perldata
      This isn't odd. It's supposed to do that.

      Are you saying defined behavior is never odd?!? That's quite a bold statement, and one I'm certainly not prepared to make (especially in this case, where I do indeed find the defined behavior a bit odd, even if it's well documented and I already knew what it was). :-)

      Now what doc is that in?

      This @ISA my( $cool ) %SIG
        I already told you. It's perldata.
Re: Hash to Scalar Assignment Oddity
by borisz (Canon) on Jan 26, 2006 at 15:47 UTC
    The first value is the number of used entries and the second the number of slots. Read it as we use currently 3 from 8 entries. You can set the slots if you like with:
    keys %db = 1000; $db = %db; print $db;
Re: Hash to Scalar Assignment Oddity
by ikegami (Pope) on Jan 26, 2006 at 17:16 UTC

    In list context, the hash returns
    ('one', 1, 'two', 2, 'three', 3)
    (but not necessarily in that order). So
    print(%db, "\n");
    is the same as
    print('one', 1, 'two', 2, 'three', 3, "\n");
    When you pass a list to print, it does
    join($,, LIST)
    So the above print is equivalent to
    print(join($,, 'one', 1, 'two', 2, 'three', 3, "\n"));

    However, in scalar context, the hash some information about its buckets. To do emulate the
    behaviour of print, do
    $db = join($,, %db);


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://525734]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2016-08-26 05:33 GMT
Find Nodes?
    Voting Booth?
    The best thing I ever won in a lottery was:

    Results (366 votes). Check out past polls.