Beefy Boxes and Bandwidth Generously Provided by pair Networks Joe
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Wrong result for "length keys %$hashref"?

by samwyse (Scribe)
on Mar 14, 2011 at 19:34 UTC ( #893123=perlquestion: print w/ replies, xml ) Need Help??
samwyse has asked for the wisdom of the Perl Monks concerning the following question:

I have the following code, where "length keys" is returning one when I expect it to return three. Any ideas about what's going on? BTW, this is Strawberry Perl 5, version 12, subversion 1 (v5.12.1) built for MSWin32-x86-multi-thread.
print length keys %$hashref; print join ',', keys %$hashref; print Dumper $hashref;
produces the following (note that keys have been changed to protect privacy, they are actually 60-80 characters in length)
1 x,y,z $VAR1 = { 'x' => 0, 'y' => 0, 'z' => 0 };

Comment on Wrong result for "length keys %$hashref"?
Select or Download Code
Re: Wrong result for "length keys %$hashref"?
by toolic (Chancellor) on Mar 14, 2011 at 19:47 UTC
    I think you want scalar instead of length. This prints 3:
    use warnings; use strict; my $hashref = { 'x' => 0, 'y' => 0, 'zzz' => 0 }; print scalar keys %$hashref;
Re: Wrong result for "length keys %$hashref"?
by philipbailey (Chaplain) on Mar 14, 2011 at 19:48 UTC

    The documentation of length answers your question:

    'length Returns the length in characters of the value of EXPR. If EXPR is omitted, returns length of $_. Note that this cannot be used on an entire array or hash to find out how many elements these have. For that, use "scalar @array" and "scalar keys %hash" respectively.'

Re: Wrong result for "length keys %$hashref"?
by ikegami (Pope) on Mar 14, 2011 at 19:54 UTC

    I prefer 0+ over scalar. It's a little more self-documenting.

    my %h = (a=>1, b=>2); print 0+keys(%h), "\n"; my @a = qw( a b c ); print 0+@a, "\n";
      That's only more self-documenting if you already understand list vs. scalar context. If a junior programmer saw that they would say WTF and have no idea where to look next. If you used scalar, they might not know exactly what it did but they'd have a direct pointer to documentation that would explain exactly what the intent of the code was.
        If you used scalar, they might not know exactly what it did...

        A Perl programmer who doesn't understand scalar context has no business programming alone.

        With that said, this is one of the few places where using the explicit scalar operator makes sense.

        You're assuming code exists in isolation. I can't think of any code that needs the number of elements in a hash that would be unclear no matter how you spelled

        0+keys(%h)

        But that doesn't mean they're all equal.

        • The 0+ points out that something special is happening, whereas scalar() just looks like a function call. A function call that doesn't exist. There's not even an op for it.

        • The 0+ points out that a number is going to be returned, confirming what one might think keys is doing.

        If you used scalar, they might not know exactly what it did but they'd have a direct pointer to documentation that would explain exactly what the intent of the code was.

        I think they'd be better off reading the docs for keys, not scalar. The former lists the two possible return values for keys. The understanding of context will follow.

Re: Wrong result for "length keys %$hashref"?
by cdarke (Prior) on Mar 14, 2011 at 23:30 UTC
    Among the excellent replies above I don't think anyone explained explicitly why you are getting the answer 1 from length, although maybe it is implied.

    length takes a scalar, so it uses keys %$hashref in scalar context. That gives 3, but length converts that to text '3', which is 1 character.

    For example:
    use warnings; use strict; my $hashref = {1..20}; print scalar(keys %$hashref)."\n"; print length keys %$hashref;
    Gives:
    10 2
    because there are 2 characters in "10".

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (8)
As of 2014-04-20 17:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (485 votes), past polls