oracular (3) Tie::AliasHash.3pm.gz

Provided by: libtie-aliashash-perl_1.02-1_all bug

NAME

       Tie::AliasHash - Hash with aliases key (multiple keys, one value)

SYNOPSIS

         use Tie::AliasHash;

         tie %hash, 'Tie::AliasHash';

         $hash{ 'foo', 'bar' } = 'baz';

         print $hash{foo}; # prints 'baz'
         print $hash{bar}; # prints 'baz' too

         $hash{bar} = 'zab'; # $hash{foo} is changed too
         print $hash{foo}; # prints 'zab'

DESCRIPTION

       Tie::AliasHash creates hashes that can have multiple keys for a single value. This means that some keys
       are just 'aliases' for other keys.

       The example shown in the synopsys above creates a key 'foo' and an alias key 'bar'. The two keys share
       the same value, so that fetching either of them will always return the same value, and storing a value in
       one of them will change both.

       The only difference between the two keys is that 'bar' is not reported by keys() and each():

         use Tie::AliasHash;
         tie %hash, 'Tie::AliasHash';
         tied(%hash)->add_alias( 'foo', 'bar' );
         foreach $k (keys %hash) { print "$k\n"; } # prints 'foo'

       To get the 'real' keys and the aliases together, use the "allkeys" function:

         use Tie::AliasHash;
         tie %hash, 'Tie::AliasHash';
         tied(%hash)->add_alias( 'foo', 'bar' );
         foreach $k (tied(%hash)->allkeys) { print "$k\n"; } # prints 'foo' and 'bar'

       You can create alias keys with 3 methods:

       •   pre-declaring them while tieing the hash

           The 'tie' constructor accepts an optional list of key names and aliases.  The synopsis is:

             tie %HASH, 'Tie::AliasHash',
               KEY => ALIAS,
               KEY => [ALIAS, ALIAS, ALIAS, ...],
               ...

       •   explicitly with the add_alias method

             tied(%hash)->add_alias( KEY, ALIAS );
             tied(%hash)->add_alias( KEY, ALIAS, ALIAS, ALIAS, ... );

       •   implicitly with a multiple-key hash assignement

             $hash{ KEY, ALIAS } = VALUE;
             $hash{ KEY, ALIAS, ALIAS, ALIAS, ... } = VALUE;

           The list of keys and aliases can be either an array reference, eg.:

             $hash{ [ 'foo', 'bar', 'baz' ] } = $value;
             $hash{ \@foobarbaz } = $value;

           or an explicit list, eg.:

             $hash{ qw(foo bar baz) } = $value;
             $hash{ @foobarbaz } = $value;

           Be warned that, with the last example, Perl uses the $; variable (or subscript separator), which
           defaults to '\034' (ASCII 28). This can cause problems if you plan to use keys with arbitrary ASCII
           characters. Always use the first form when in doubt. Consult perlvar for more information.

   EXPORT
       None by default. You can optionally export the "allkeys" function to your main namespace, so that it can
       be used like the builtin "keys".

         use Tie::AliasHash 'allkeys';
         tie %hash, 'Tie::AliasHash';
         foreach $k (allkeys %hash) { print "$k\n"; }

       But see CAVEATS below for important information about "allkeys".

   METHODS
       add_alias( KEY, ALIAS, [ALIAS, ALIAS, ...] )
           Add one or more ALIAS for KEY. If KEY itself is an alias, the aliases are added to the real key which
           KEY points to.

       aliases( KEY )
           Returns a list of all the aliases defined for KEY. If KEY itself is an alias, returns the real key
           pointed by KEY, as well as any other alias (thus excluding KEY itself) it has.

       allkeys
           Returns all the (real) keys of the hash, as well as all the aliases.

       is_alias( KEY )
           Returns true if the specified KEY is an alias, false otherwise (either if KEY does not exists in the
           hash, or it is a real key).

       is_key( KEY )
           Returns true if the specified KEY is a real key, false otherwise (either if KEY does not exists in
           the hash, or it is an alias for another key).

       remove( KEY )
           Remove KEY from the hash: if KEY is a real key, it is removed with all its aliases. If KEY is an
           alias, only the alias is removed.  This is different from the builtin "delete", see CAVEATS below.

       remove_alias( ALIAS )
           Removes the specified ALIAS from its real key. ALIAS is no longer an alias and can be assigned its
           own value. The real key which ALIAS used to point to is left unchanged.

       remove_aliases( KEY )
           Removes all the aliases defined for KEY.

       remove_jolly( )
           Removes the 'jolly' key from the hash. Operations on non-existant keys are restored to normality.

       set_jolly( KEY )
           Sets the 'jolly' key to KEY. When you set a jolly key, all fetch and store operations on non-existant
           keys will be done on KEY instead.

CAVEATS

       This module can generate a wonderful amount of confusion if not used properly. The package should really
       have a big 'HANDLE WITH CARE' sticker on it. Other than paying special attention to what you're doing,
       you should be aware of the following subtlenesses:

       •   transitivity

           Aliases are 'transitive', and always resolve to their aliased key. This means that if you write:

             use Tie::AliasHash;
             tie %hash, 'Tie::AliasHash';
             tied(%hash)->add_alias( 'foo', 'bar' );
             tied(%hash)->add_alias( 'bar', 'baz' );

           $hash{baz} is created as an alias for $hash{foo}, not for $hash{bar} (which isn't a real key). This
           also means that if you later change $hash{bar} to point to something else, you haven't changed
           $hash{baz}:

             tied(%hash)->add_alias( 'gup', 'bar' );
             # $hash{bar} is now really --> $hash{gup}
             # $hash{baz} is still      --> $hash{foo}

       •   delete

           The builtin "delete" function resolves aliases to real keys, so it deletes everything even when
           called on an alias:

             use Tie::AliasHash;
             tie %hash, 'Tie::AliasHash';
             tied(%hash)->add_alias( 'foo', 'bar' );

             delete $hash{bar}; # deletes $hash{foo} too!

           To delete an alias leaving its key intact, use the "remove_alias" method instead:

             use Tie::AliasHash;
             tie %hash, 'Tie::AliasHash';
             tied(%hash)->add_alias( 'foo', 'bar' );

             tied(%hash)->remove_alias( 'bar' ); # $hash{foo} remains intact

       •   exists

           The builtin "exists" function returns true on aliases too:

             use Tie::AliasHash;
             tie %hash, 'Tie::AliasHash';
             tied(%hash)->add_alias( 'foo', 'bar' );

             print exists $hash{'foo'}; # TRUE
             print exists $hash{'bar'}; # TRUE

           To distinguish between aliases and real keys, use the "is_key" method:

             print exists $hash{'foo'} and tied(%hash)->is_key('foo'); # TRUE
             print exists $hash{'bar'} and tied(%hash)->is_key('bar'); # FALSE

       •   allkeys

           If you export "allkeys" into your main namespace, it can be used as the builtin "keys" in the
           following code:

             use Tie::AliasHash 'allkeys';
             tie %hash, 'Tie::AliasHash';
             foreach $key (allkeys %hash) { print "$key\n"; }

           But note that "allkeys" is always a function call, so this does not work as you expect:

             foreach $key (sort allkeys %hash) { print "$key\n"; }

           You have to fool "sort", or it will use "allkeys" as its sort routine.  This can be done by providing
           an explicit sort routine, or forcing the result of "allkeys" to be interpreted as an array by
           referencing-dereferencing it, or with a two-step operation where you first assign "allkeys" to an
           array, and then operate on it:

             foreach $key (sort { $a cmp $b } allkeys %hash) { print "$key\n"; }
             foreach $key (sort @{[ allkeys %hash ]}) { print "$key\n"; }

             @allkeys = allkeys %hash;
             foreach $key (sort @allkeys) { print "$key\n"; }

       •   the 'jolly' key

           The most potentially confusing feature of this module is the 'jolly' key. When you set a value for
           it, all 'unknown' keys become aliases for the jolly key. This means that you can't create new keys in
           the hash, because if a key does not exists, the value will be 'redirected' to the jolly key.

           We make an example of how this works and for what can be useful.  Suppose you have a table of records
           with a 'city' field. You want to count the occurrencies for Rome, Paris and London (possibly
           expressed in different languages), and count every other city as 'Other'.

             tie %cities, 'Tie::AliasHash';

             $cities{['Rome', 'Roma', 'Rom']} = 0;
             $cities{['Paris', 'Parigi']} = 0;
             $cities{['London', 'Londra', 'Londres']} = 0;
             $cities{'Other'} = 0;
             tied(%cities)->set_jolly('Other');

             while($city = get_city()) {
                 $cities{$city}++;
             }
             foreach $city (sort keys %cities) {
                 print "$city:\t$cities{$city}\n";
             }

           A possible output for the above script can be:

             London: 4
             Other:  92
             Paris:  7
             Rome:   16

           Also note that the use of the jolly key is limited to fetch and store, it does not affect other hash
           operations, like exists, delete, each, keys and values.

HISTORY

       v1.02 (11 Mar 2016)
           Moved to github, using Build.PL instead of Makefile.PL, added license.

       v1.01 (26 Jun 2003)
           Fixed a bug in the EXISTS sub, now works as documented (thanks wk)

       v1.00 (07 Mar 2001)
           First released version

       v0.01 (20 Feb 2001)
           Original version; created by h2xs 1.20 with options

             -CAXn Tie::AliasHash

AUTHOR

       Aldo Calpini <dada@perl.it>