in reply to How to test for empty hash?

The node Truth and Falsehood also briefly discusses this. In short, a hash in boolean context returns a false value when it is empty, so if (!%hash) will portably detect an empty hash. To portably get the number of keys in a hash, use keys in scalar context; scalar(%hash) is not backwards compatible for counting keys (as the documentation quoted by LanX explains).

Minor edits clarification.

Replies are listed 'Best First'.
Re^2: How to test for empty hash?
by ikegami (Patriarch) on Aug 06, 2021 at 09:34 UTC

    This is a bit confusingly written.

    The question was about checking if a hash is empty, and %h in scalar context can be used to do this portably (though the relative recent change makes it more efficient).


    That said,

    %h in scalar context can't be used to get the number of keys portably.

    keys(%h) in scalar context can be used to get the number of keys portably and efficiently.

    That's not true. You could aways use There was a relatively recent change thatefficiency of hash in boolean context

    Seeking work! You can reach me at ikegami@adaelis.com

      This is a bit confusingly written. That's not true. You could aways use There was a relatively recent change thatefficiency of hash in boolean context
Re^2: How to test for empty hash?
by LanX (Saint) on Aug 06, 2021 at 09:16 UTC
    update: it's wrong, only read further to learn from mistakes ;-)


    > to portably get the number of keys in a hash, use keys in scalar context; scalar(%hash) is not backwards compatible

    nitpick for the sake of fun, b/c of the magic of the string_to_number conversion using it as a number will portably work.

    (tho I'd also prefer using keys here :)

    DB<1> p $] 5.024001 DB<2> %h=(a=>0) DB<3> p scalar %h 1/8 DB<4> p 0+ %h 1 DB<5>

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      nitpick for the sake of fun, b/c of the magic of the string_to_number conversion using it as a number will portably work.

      Sorry, no, it doesn't:

      $ perlbrew exec perl -e '%h="a".."z";warn"$] ".keys%h," ".%h," ",0+%h, +"\n"' >/dev/null 5.034000 13 13 13 5.032001 13 13 13 5.030003 13 13 13 5.028003 13 13 13 5.026003 13 13 13 5.024004 13 8/16 8 5.022004 13 10/16 10 5.020003 13 7/16 7 5.018004 13 11/16 11 5.016003 13 9/16 9 5.014004 13 9/16 9 5.012005 13 9/16 9 5.010001 13 9/16 9 5.010000 13 9/16 9 5.008009 13 9/16 9 5.008001 13 12/16 12 5.006002 13 4/8 4

      Minor edits to shorten output.

        damn you're right...

        ... of course #buckets <= #keys because of collisions.

        Thanks for the correction! :)

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery