Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

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?


dsb
This @ISA my( $cool ) %SIG

Comment on Hash to Scalar Assignment Oddity
Download Code
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).

    Phil

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;
    Boris
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);

    References:
    hash
    print
    $,

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?


      dsb
      This @ISA my( $cool ) %SIG
        I already told you. It's perldata.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2014-09-16 22:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (50 votes), past polls