NAME
Tie::Proxy::Hash - Effieciently merge & translate hashes.
SYNOPSIS
my (%hash, $ref);
$ref = tie %hash, 'Tie::Proxy::Hash', (bart => +{a => 1,
b => 2},
maggie => +{a => 5,
c => 6,
e => 10},
);
$hash{a} == 1; # true
$hash{b} == 2; # true (bart supercedes maggie)
$hash{c} == 6; # true
! defined $hash{d}; # true
$hash{e} == 10; # true
$hash{c} = 9; # set in maggie
$hash{d} = 12; # set in default
$hash{f} = 11; # set in default
$ref->add_hash('lisa', +{d => 3, b => 4});
$hash{c} == 9; # true
$hash{b} == 2; # true (bart overrides lisa)
$hash{d} == 3; # true (lisa overrides default)
$hash{f} == 11; # true (only default knows 'f')
DESCRIPTION
Proxy hash requests for one or more other hashes, with intermediate value translation.
Tie::Proxy::Hash 'merges' hashes by maintaining a list of hashes to look up, and each key requested is looked up in each hash in order until a hit is found. Resultant values may be subject to a translating subr. In this way, hashes may be merged without the cost of by-value copying.
A default backing hash is provided to store values not present in other hashes.
Tying
$ref = tie %hash, 'Tie::Proxy::Hash',
bart => +{a => 1, b => 2},
maggie => +{a => 5, c => 6, e => 10} => sub {10*$_[0]},
;
Any arguments passed to tie
are palmed off onto add_hash.
Retrieving Values
Values are retrieved by checking each hash in the order of insertion; the first hash found in which a given key exists supplies the value. The value is subject to translation if the given hash has an associated translator.
INSTANCE HIGHER-LEVEL PROCEDURES
add_hash
- SYNOPSIS
-
$ref->add_hash('bart', +{ a => 1, b => 2 }); $ref->add_hash('lisa', +{ c => 3, b => 4 }, sub { $_[0] * 20 });
- ARGUMENTS
-
- name
-
The name by which to refer to the hash (for future manipulations, e.g., remove_hash). The name must be a valid perl identifier --- a non-empty string of word characters not beginning with a digit.
If a member with the given name already exists, the hash is updated (and the translator is updated/inserted/removed accordingly), but the order does not change. Hence, following the synopsis by calling
$ref->add_hash('bart', +{ a => 5, b => 6 });
(without an intervening
remove_hash
) will set the effective value ofb
to 6, for the new 'bart' hash will still be checked before the 'lisa' hash.If a member with the given name does not already exist (including if it was deleted with remove_hash), the hash is added at the end of the queue.
Hashes inserted with
add_hash
are always checked before the default hash, even if the default hash has values that were set prior to the named hash(es) being inserted. - hash
-
The hash to add in, as a hashref. For efficiency, this hash is stored within as is. Therefore, if a reference to the same hash is manipulated externally, these manipulations will be visible to the Proxy Hash. Caveat Emptor.
- translator
-
Optional. If defined, all values retrieved from this hash are run through the given code ref before being returned to the caller. The subr is called with a single argument, the hash value, and is expected to return a single value (which is passed back to the caller).
The translator is only called to translate values for which keys exist in the given hash; the translator is never called to create new values.
The presence of a translator prevents any values being set in the hash (via the
Tie::Proxy::Hash
interface) (since there is no reverse translation facility). Therefore, if a value is set that would otherwise be stored in a translated hash, the key in that hash is deleted instead (to maintain the identity$h{c} = $x; $h{c} == $x
). The storage then falls through to the next untranslated hash (possibly the default hash). This is why the default hash has no translator.my ($ref, %hash); $ref = tie %hash, 'Tie::Proxy::Hash'; $ref->add_hash('bart', +{ a => 1, b => 2 }); $ref->add_hash('lisa', +{ c => 3, b => 4 }, sub { $_[0] * 20 }); $hash{c} = 5; # Sets c in the default hash, deletes 3 from lisa.
The order of calling add_hash
is relevant; each hash is checked in order of insertion via add_hash
. Therefore, given the example in the synopsis, the 'bart' hash is checked for values before the 'lisa' hash. Hence the effective value of b
is 2.
remove_hash
- SYNOPSIS
-
$ref->remove_hash('bart');
- ARGUMENTS
-
- name
-
Name of the member hash to remove. An exception will be raised if no such member exists.
Removing a hash wipes any present translation, and the named hash loses its place in the queue.
EXAMPLES
BUGS
REPORTING BUGS
Email the author.
AUTHOR
Martyn J. Pearce fluffy@cpan.org
COPYRIGHT
Copyright (c) 2003 Martyn J. Pearce. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.