Some time back we added support to Perl for locked or restricted hashes. (See Hash::Util and fields.pm). The basic idea is that you can set up a hash, and then "lock" it, at which point access to unregistered keys in the hash, either write OR read, will cause an exception.

The basic idea was to work around Perl's lack of a true "struct"/"object" where it would be conventional to have compile time exceptions when accessing a non-existent member, or when accessing a late bound object in many languages which should produce a run time exception. Unfortunately restricted hashes do not support compile time exceptions, so we only get run time exceptions.

All of this comes at a cost, a cost that is imposed on every hash function usage, either by your code, or by Perl itself. So for instance every time perl looks up a variable from the stash it has to execute code that is *never* used internally. Similarly, whenever you populate a hash to build a report, or whatever you are paying a cost for restricted hashes even if you aren't using them.

IMO even worse is that locked hashes are basically very unperlish. In my experience they are there to provide a safety blanket to people from other languages who feel unsafe without these kind of protections. In my work code the use of locked hashes is basically zero. Almost every time someone uses locked hashes it is not for their intended purpose of making OO "easier", but rather to make a read-only hash. However even that use case is not well served by locked hashes, as locked hashes *die* when you try to access a non-existent key, which goes against the general expectations of a read-only hash.

To put this context, some of the perl core developers have started work on making Perl's hash function pluggable and vtable driven. This would mean that we can use different hash implementations in different places, and people could produce efficient C level code that made Perl use, for instance, a B+tree for storing its hashes. Or use robin-hood hashing, or any other data structure suitable for implementing associative arrays.

However it also means we have to put a lot of thought into what kind of API a hash exposes. If the API has to support locked hashes, then any alternative implementation has to support locked hashes, and by extension you and I and everyone using Perl will have to pay the price for those locked hashes. On the other hand, if we do not have to provide an API for locking hashes we can instead provide a bespoke lockable hash implementation via a CPAN module that supports sane locking primitives (and who knows, maybe even compile time exceptions).

Another context to consider is that Perl hashes are really a work around for the fact that Perl has not real "object" type. So locked hashes impose a non-trivial wide scope cost to provide a work around. So what happens if the core hackers get their shit together and add a true object type and grammar to perl? Will we still have to pay the price of locked hashes?

So, I am arguing that we should deprecate and remove locked hashes from core, and reimplement fields.pm using a custom hash table implementation built on top of the pluggable hash API that we have started investigating.

What do you think? Do you use Hash::Util::lock_hash() or similar methods? What is your impression and experience of locked hashes and fields.pm? Useful? Useless? Good idea but flawed implementation? Something else?

Cheers,

Yves