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

Re: [PATCH for discussion] new feature: clamp %hash

Thread Previous | Thread Next
July 23, 2001 11:30
Re: [PATCH for discussion] new feature: clamp %hash
Message ID:
On Thu, Jul 19, 2001 at 11:15:12AM -0700, Jeffrey Friedl wrote:
> I have long wished that I could mark a hash such that no new keys could
> be added to it -- sort of like a "use strict" for hashes in that if you
> intended
> 	$foo->{Quiet} = 1;
> and by accident typed
> 	$foo->{Quite} = 1;
> you'd get an error.
> I know you can do this with pseudohashes, but it's not always convenient to
> use one, so I've made an attempt to add it myself -- patch follows below.
> The functionality is what's important to me -- how I happened to have
> implemented it will be met with horror by many, I'm sure. I don't claim to
> know much about Perl internals or Perl language design. (But I'm sure I'll
> find out when I see the replies :-)
> I added a new reserved word (I can hear the cringing already) "clamp".
> To clamp down on a hash and disallow access to nonexistant keys:
>    clamp %hash, 1
> To unclamp:
>    clamp %hash, 0
> To query
>    my $clamped = clamp %hash;

I think this is yet another example of "there's something wrong/missing
in Perl, let's fix it with a kludge".

The real underlaying problems here are 1) Perl doesn't have structs,
but more importantly, 2) Perl only gives you one instance variable per
object. Pseudo-hashes tried to fix the symptoms, not the cause and
they didn't succeed. "clamp" tries to fix the symptoms too - and not
the cause.

The problem isn't really that you can make typos with hashkeys, the
problem is that you're almost forced to use hashes in cases you really
wanted something else, but the best alternative Perl gives you are hashes.

While I agree such a "clamp" function feels better than pseudo-hashes,
I feel less than thrilled by the idea explaining the reasoning about
"clamp" to my students - or collegeas for that matter.

> My thinking here is that when you create the hash (and I'm mostly thinking
> in a using-a-hash-as-an-object mode), you would pre-create all fields
> you'll ever need:
>    sub Employee::New($$$)
>    {
>         my $class = shift;
>         my $lastname = shift;
>         my $firstname = shift;
>         my $ref = bless {
>              Family  => $lastname,
>              Given   => $firstname,
>              DOB     => undef,
>              EmpNum  => undef,
>              Manager => undef,
>         }, $class;
>         clamp %$ref, 1;  ## only those keys listed above are ever used
>         return $ref;
>    }

There is another way to fix the problem of "wanting to have strictness
for hashkeys" here, and that's by promoting the keys to variables, and
making the object the key:

     my (%Family, %Given, %DOB, %EmpNum, %Manager);

     sub Employee::New ($$$) {
         my $class        = shift;
         my $lastname     = shift;
         my $firstname    = shift;

         my $self         = bless [] => $class;

         $Family  {$self} = $lastname;
         $Given   {$self} = $firstname;
         $DOB     {$self} = undef;
         $EmpNum  {$self} = undef;
         $Manager {$self} = undef;



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