keys in scalar context now returns the number of keys

Starting in v5.26, a hash in scalar context evaluates to the number of keys in the hash. You might have thought that it always did that just like an array (not a list!) in scalar context evaluates to the number of items. But nopeā€”it evaluated to a seemingly useless number called the “hash statistics”. Now it’s fixed to do what most people thought it already did. For what it’s worth, keys (or values) in scalar context already provided the count.

Here are several uses of a hash in scalar context. With an empty hash you accidentally get the number of keys, but after that it looks like a fraction. That’s the statistics of hash bucket use. The hash allocated a certain number of “buckets” to store things. Don’t worry about what that is unless you feel like spending your free time perusing the perl source code. The bottom number of the fraction is the count of the allocated buckets. The top is the number of buckets actually used. A normal hash spreads out what it stores and allocates extra buckets for future values. In these programs you can see that the hash starts with a lot of buckets and allocates more when over half of them are used (and adding more keys doesn’t necessarily mean using a new bucket):

$ perl5.24.3 -le '%h = qw(); print scalar %h'
0
$ perl5.24.3 -le '%h = qw(q b); print scalar %h'
1/8
$ perl5.24.3 -le '%h = qw(a b); print scalar %h'
1/8
$ perl5.24.3 -le '%h = qw(a b c d); print scalar %h'
2/8
$ perl5.24.3 -le '%h = qw(a b c d e f g h ); print scalar %h'
3/8
$ perl5.24.3 -le '%h = qw(a b c d e f g h i j ); print scalar %h'
4/8
$ perl5.24.3 -le '%h = qw(a b c d e f g h i j k l); print scalar %h'
4/8
$ perl5.24.3 -le '%h = qw(a b c d e f g h i j k l m n ); print scalar %h'
5/8
$ perl5.24.3 -le '%h = qw(a b c d e f g h i j k l m n o p); print scalar %h'
6/16

Running these same programs under v5.26 is boring. You get back the number of keys in all cases:

$ perl5.26.2 -le '%h = qw(a b c d e f g h i j k l m n o p); print scalar %h'
8

This doesn’t mean that I recommend using a hash like this, but then I use an array like this all the time. I’ve probably spent too much time writing keys %hash to change now.