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; $self; } AbigailThread Previous | Thread Next