Tie::Proxy::Hash - Effieciently merge & translate hashes.
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')
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.
$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.
tie
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.
$ref->add_hash('bart', +{ a => 1, b => 2 }); $ref->add_hash('lisa', +{ c => 3, b => 4 }, sub { $_[0] * 20 });
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 of b to 6, for the new 'bart' hash will still be checked before the 'lisa' hash.
remove_hash
b
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.
add_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.
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.
Tie::Proxy::Hash
$h{c} = $x; $h{c} == $x
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.
$ref->remove_hash('bart');
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.
Email the author.
Martyn J. Pearce fluffy@cpan.org
fluffy@cpan.org
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.
To install Tie::Proxy::Hash, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Tie::Proxy::Hash
CPAN shell
perl -MCPAN -e shell install Tie::Proxy::Hash
For more information on module installation, please visit the detailed CPAN module installation guide.