8 our @ISA = qw(Exporter);
9 our @EXPORT_OK = qw(lock_keys unlock_keys lock_value unlock_value
10 lock_hash unlock_hash hash_seed
16 Hash::Util - A selection of general-utility hash subroutines
20 use Hash::Util qw(lock_keys unlock_keys
21 lock_value unlock_value
25 %hash = (foo => 42, bar => 23);
27 lock_keys(%hash, @keyset);
30 lock_value (%hash, 'foo');
31 unlock_value(%hash, 'foo');
36 my $hashes_are_randomised = hash_seed() != 0;
40 C<Hash::Util> contains special functions for manipulating hashes that
41 don't really warrant a keyword.
43 By default C<Hash::Util> does not export anything.
45 =head2 Restricted hashes
47 5.8.0 introduces the ability to restrict a hash to a certain set of
48 keys. No keys outside of this set can be added. It also introduces
49 the ability to lock an individual key so it cannot be deleted and the
50 value cannot be changed.
52 This is intended to largely replace the deprecated pseudo-hashes.
61 lock_keys(%hash, @keys);
63 Restricts the given %hash's set of keys to @keys. If @keys is not
64 given it restricts it to its current keyset. No more keys can be
65 added. delete() and exists() will still work, but will not alter
66 the set of allowed keys. B<Note>: the current implementation prevents
67 the hash from being bless()ed while it is in a locked state. Any attempt
68 to do so will raise an exception. Of course you can still bless()
69 the hash before you call lock_keys() so this shouldn't be a problem.
73 Removes the restriction on the %hash's keyset.
77 sub lock_keys (\%;@) {
78 my($hash, @keys) = @_;
80 Internals::hv_clear_placeholders %$hash;
82 my %keys = map { ($_ => 1) } @keys;
83 my %original_keys = map { ($_ => 1) } keys %$hash;
84 foreach my $k (keys %original_keys) {
85 die sprintf "Hash has key '$k' which is not in the new key ".
86 "set at %s line %d\n", (caller)[1,2]
90 foreach my $k (@keys) {
91 $hash->{$k} = undef unless exists $hash->{$k};
93 Internals::SvREADONLY %$hash, 1;
95 foreach my $k (@keys) {
96 delete $hash->{$k} unless $original_keys{$k};
100 Internals::SvREADONLY %$hash, 1;
106 sub unlock_keys (\%) {
109 Internals::SvREADONLY %$hash, 0;
117 lock_value (%hash, $key);
118 unlock_value(%hash, $key);
120 Locks and unlocks an individual key of a hash. The value of a locked
121 key cannot be changed.
123 %hash must have already been locked for this to have useful effect.
127 sub lock_value (\%$) {
128 my($hash, $key) = @_;
129 carp "Cannot usefully lock values in an unlocked hash"
130 unless Internals::SvREADONLY %$hash;
131 Internals::SvREADONLY $hash->{$key}, 1;
134 sub unlock_value (\%$) {
135 my($hash, $key) = @_;
136 Internals::SvREADONLY $hash->{$key}, 0;
146 lock_hash() locks an entire hash, making all keys and values readonly.
147 No value can be changed, no keys can be added or deleted.
151 unlock_hash() does the opposite of lock_hash(). All keys and values
152 are made read/write. All values can be changed and keys can be added
162 foreach my $key (keys %$hash) {
163 lock_value(%$hash, $key);
169 sub unlock_hash (\%) {
172 foreach my $key (keys %$hash) {
173 unlock_value(%$hash, $key);
184 my $hash_seed = hash_seed();
186 hash_seed() returns the seed number used to randomise hash ordering.
187 Zero means the "traditional" random hash ordering, non-zero means the
188 new even more random hash ordering introduced in Perl 5.8.1.
193 Internals::hash_seed();
200 Note that the trapping of the restricted operations is not atomic:
203 eval { %hash = (illegal_key => 1) }
205 leaves the C<%hash> empty rather than with its original contents.
209 Michael G Schwern <schwern@pobox.com> on top of code by Nick
210 Ing-Simmons and Jeffrey Friedl.
214 L<Scalar::Util>, L<List::Util>, L<Hash::Util>,
215 and L<perlsec/"Algorithmic Complexity Attacks">.