Tied hashes#
A tied hash is the richest of the tie types, because a hash does more than read and write single elements - it iterates, it reports its size, it tests for key existence, and it clears. Each of those is a separate hook. Hashes were the first Perl data type to be tied (the original use case was binding %hash to an on-disk DBM file), and the interface still reflects that heritage.
The full method menu is on the tie reference page. This chapter builds one class and explains each hook, with attention to the part that trips people up: the iteration protocol.
A complete class#
A hash whose keys are case-insensitive - $h{Name} and $h{NAME} address the same slot:
use v5.36;
package CaseInsensitive {
sub TIEHASH { my $class = shift; return bless {}, $class }
sub STORE { my ($self, $key, $val) = @_; $self->{lc $key} = $val }
sub FETCH { my ($self, $key) = @_; return $self->{lc $key} }
sub EXISTS { my ($self, $key) = @_; return exists $self->{lc $key} }
sub DELETE { my ($self, $key) = @_; return delete $self->{lc $key} }
sub CLEAR { my $self = shift; %$self = () }
sub FIRSTKEY { my $self = shift; my $reset = keys %$self; return each %$self }
sub NEXTKEY { my $self = shift; return each %$self }
sub SCALAR { my $self = shift; return scalar %$self }
}
tie my %h, 'CaseInsensitive';
$h{Name} = 'Ada';
$h{EMAIL} = 'ada@example.org';
say $h{name}; # Ada
say $h{email}; # ada@example.org
say exists $h{NAME} ? 'yes' : 'no'; # yes
say scalar %h ? 'nonempty' : 'empty'; # nonempty
for my $k (sort keys %h) {
say "$k => $h{$k}";
}
# email => ada@example.org
# name => Ada
The object is a blessed hash ref used as the real storage; the hooks lower-case the key before touching it. Notice that iteration returns the stored (lower-cased) keys, which is exactly what a case-insensitive hash should do.
The method contract#
TIEHASH classname, LISTThe constructor. Returns a blessed reference - usually but not necessarily a hash ref - that becomes the tied object.
FETCH this, key/STORE this, key, valueSingle-element read and write, the same pair as for scalars but with a key argument.
STORE’s return value is ignored.EXISTS this, key/DELETE this, keyBack the
existsanddeletebuilt-ins.DELETE’s return value becomesdelete’s return value; to match a plain hash, return whatFETCHwould have returned for that key before removing it.CLEAR thisTriggered when the whole hash is emptied, typically by assigning the empty list (
%h = ()). Remove everything.FIRSTKEY this/NEXTKEY this, lastkeyThe iteration protocol - see below. Together they drive
keys,values, andeach.SCALAR thisCalled when the hash is evaluated in scalar or boolean context (
scalar %h,if (%h), and since 5.28keys %hin boolean context). Return a value that is true when the hash is non-empty and false when empty.DESTROY thisandUNTIE thisOptional cleanup hooks, identical in role to the scalar case.
UNTIEis covered under the untie gotcha below.
The iteration protocol#
This is the part of the hash interface that has no analogue in the scalar one, and the part that most often goes wrong.
When a keys, values, or each iteration begins, the runtime calls FIRSTKEY to get the first key, then NEXTKEY repeatedly, passing the previously returned key each time, until a method returns the empty list or undef. Both are always called in scalar context and should return just a key; the runtime calls FETCH itself to get each value.
Two rules keep iteration correct:
FIRSTKEYmust reset any internal iterator. When the backing store is a real hash, evaluatekeys %$selfin void or scalar context first - that resets Perl’s per-hasheachcursor - then calleach. The throwawaymy $reset = keys %$selfin the example does exactly this. Skip it and a freshkeys %hmay resume from wherever the last iteration stopped.Signal the end with the empty list. When the backing store is not a real hash and has no
eachof its own, return the empty list (orundef) once you have handed out the last key.
Why SCALAR is worth defining#
Without a SCALAR method, the runtime guesses at the hash’s truth in boolean context, and the guess can be wrong - notably, it may report a hash as non-empty right after you have emptied it by repeated DELETE. If if (%tied_hash) matters to your callers, define SCALAR and return the real answer, as the example does with scalar %$self.
Call timing#
$h{k}reads →FETCH;$h{k} = $v→STORE.exists $h{k}→EXISTS;delete $h{k}→DELETE.%h = ()→CLEAR;%h = (a => 1)→CLEARthenSTORE.keys %h/values %h/each %h→FIRSTKEYonce, thenNEXTKEYper step.keysandvaluesin list context callFETCHfor each key as well.scalar %h,if (%h)→SCALAR(if defined).A hash slice
@h{qw(a b)}callsFETCHonce per key; there is no slice hook.
Minimum viable class#
A read/write tied hash needs at least TIEHASH, FETCH, and STORE. If callers will ever iterate it, add FIRSTKEY and NEXTKEY - without them, keys and each see an empty hash. Add EXISTS and DELETE if callers use those built-ins; without them, exists/delete die at the point of use. SCALAR and CLEAR round out correctness for boolean tests and bulk emptying.
The easy way: inherit from Tie::StdHash#
Tie::StdHash (shipped inside Tie::Hash) implements the entire menu over a blessed hash ref. Inherit from it and override only the hooks that should behave differently:
package LoudHash {
use Tie::Hash;
our @ISA = ('Tie::StdHash');
sub STORE { my ($self, $k, $v) = @_; $self->{$k} = uc $v }
}
tie my %loud, 'LoudHash';
$loud{greeting} = 'hi';
say $loud{greeting}; # HI
Only STORE changes; FETCH, EXISTS, the iteration protocol, and the constructor all come from the base class. Tie::Hash (the parent) is the abstract version that supplies a default TIEHASH and new but leaves the access methods for you to write; Tie::StdHash is the concrete one you usually want.
See also#
tie- the built-in and the full hash method menutied- reach the backing object for class-specific methodseach- the iterator thatFIRSTKEY/NEXTKEYimplement; its own page documents the end-of-iteration contractTied scalars - the simpler interface this one builds on
Tie::Hash- the base-class module;Tie::StdHashis the concrete version