develooper Front page | perl.perl5.porters | Postings from November 2001

Re: restricted hashes, and other readonlyness (was "clamp...")

Thread Previous | Thread Next
Nick Ing-Simmons
November 2, 2001 00:33
Re: restricted hashes, and other readonlyness (was "clamp...")
Message ID:
Michael G Schwern <> writes:
>There seem to be many "wants" here for read-only hashes:
>    1) protect against key typos
>    2) protect against other parts of the program putting random crap
>       in your hash (usually objects and subclasses)
>    3) provide a constant hash (ie. fixed keys, fixed values)
>#1 is the "any read access to a key which doesn't exist is an error".

And write access ...

>#2 are provided by a hash with a fixed keyset, nothing more,
>nothing less.  delete(), exists(), keys() all work like regular
>hashes.  This is the basic struct.

I happen to want 2a which stops parts of the program deleting random keys
in my hash.

>#3 is just a fixed keyset plus disallowing delete() and
>$locked{$key} = 'foo';

There is also the small matter of turning on SvREADONLY on the values.

>On Thu, Nov 01, 2001 at 07:33:49AM -0800, Jeffrey Friedl wrote:
>> This natural, drop-in approach feels like The Perl Way to me, which is why
>> I feel that keys() should maintain the same returns-only-existing-keys
>> semantics.

If we disallow delete then existing keys are the allowed keys.

>I agree whole heartedly with this.  Hashes, read-only or not, are
>still hashes.  The following code:
>    delete $hash{some_allowed_key};
>    print "Nope" unless exists $hash{some_allowed_key};
>    print "Nope" unless grep { $_ eq 'some_allowed_key' } keys %hash;
>Should work the same on all built-in hashes.  Unless we have a case
>where delete() is not allowed at all.  I'm losing track.
>The drop-in argument is all the more important when you consider the
>case of passing around a read-only hash (or whatever we're calling
>it).  If I have my %struct and I want to hand it off to some function
>that just works on hashes, it just should work without special code to
>check if it's a struct or not.

Agreed - but the issue is which sub-set of hash ops is essential.
You could so the above with a %struct which did not allow delete.

>Regarding using keys() to ask what's allowed: Consider the utility of
>this.  Given that a %struct has a fixed keyset, how often are you
>going to want to know what keys are allowed?  How often are you going
>to want to know what keys are uninitialized?  Is it worth confusing
>the semantics of keys() for this (consider the extra documentation)?
>What's wrong with an XS allowed() function?

Consider me convinced on that one.

>Finally, the argument that we can shave a few bytes of memory by
>adding a few inconsistencies into the implementation seems a throwback
>to pseudo-hashes.

Aside from the (now dead) abuse of keys - the other cause for which I
am Devil's advocate is the minimalist one:

One (existing) flag bit SvREADONLY
 - error on get of non-existing key
 - error on set of non-existing key
 - delete is not allowed
 - keys is just existing code
 - therefore exists on deleted key is non issue

I want folk to explain clearly the draw back of that and why it is
not sufficient for appication X. That is which applications need to
delete members of enumerated-hash - with attendant issues of defining
"clever" magic values and defining/documenting semantics of exists and keys.

>We made these mistakes with 5.005 pseudo-hashes.

We also (IMHO) made the mistake of going out of our way to make pseudo-hashes
more hash-like than is necessary for the "struct" case

Nick Ing-Simmons

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About