This is the number of buckets in use and the total number of buckets in the hash. When used in a numeric context it will result in the first number.

If the hash is empty, perl will just give "0"

But to prevent this generation of a string and then conversion to a number you can do

scalar keys %hash

You say beware ties. Well with ties everything goes out the window as there is no knowing if the tied package will behave in a usual fashion, ie it could arrange for keys to always return an empty list, but still return values for accesses. MJD has a package Interpolation that does this.