NAME

Tie::ListKeyedHash - A system allowing the use of anonymous arrays as keys to a hash.

SYNOPSIS

   use Tie::ListKeyedHash;

   [$X =] tie %hash,  'Tie::ListKeyedHash';


   my $live_key     = ['key','items','live'];
   $hash{$live_key} = 'Hello!';

   $hash{['key','trees','grow']} = 'Goodbye!';

   print $hash{['key','items','live']},"\n";
   delete $hash{$live_key};

   my @list =  keys %{$hash{['key']}};
   print "@list\n";

   untie %hash ;

Alternatively keys are accessible as:

   $hash{'key','items','live'} = 'Hello!';

(a bare list/array for the key rather than using an anon list/array reference).

But that slows down the accesses by around 10% and cannot be used for keys that conflict with the value of the $; special variable.

Also usable via the object interface methods 'put', 'get','exists','delete','clear'. The object interface is about 2x as fast as the tied interface.

DESCRIPTION

Tie::ListKeyedHash ties a hash so that you can use a reference to an array as the key of the hash. It otherwise behaves exactly like a normal hash (including all caveats about trying to use a key as both a hash reference and a scalar value).

This frees you from needing to 'hardwire' hash references in code or having to write tree traversal code to reach arbitrary points in a hash tree.

Example:

                   ########################

 #!/usr/bin/perl

 use strict;
 use warnings;

 use Data::Dumper;

 use Tie::ListKeyedHash;

 my %example;
 tie (%example, 'Tie::ListKeyedHash');

 %example = (
     'a' => {
       'b0' => {
         'c' => 'value of c',
         'd' => 'value of d',
         'e' => {
           'f' => 'value of f',
         },
       },
       'b1' => {
         'g' => 'value of g',
       },
     },
     'h' => 'r',
 );

 my $b_key = ['a','b0'];

 my $d_key = [@$b_key,'d'];
 my $d     = $example{$d_key};
 print "d = $d\n";

 my $e_key = [@$b_key, 'e'];
 my $e     = $example{$e_key};
 print 'e = ' . Dumper ($e);

 my $f_key = [@$b_key, 'e','f'];
 my $f     = $example{$f_key};
 print "f = $f\n";

 my $h_key = ['h'];
 my $h     = $example{$h_key};
 print "h = $h\n";

                   ########################

The virtues of this particular way of accessing hash-of-hashes (HoH) vs bare hardwired derefererences or 'tree crawling' are as follows:

1) As the number of levels in a HoH increases, the tied object asymptotically approaches the speed of hardwired hash dereferencing without the loss of flexibility penalty of having to hardwire the keys into code in advance.

This gives an important property that it gets faster the deeper a HoH becomes as compared with the speed of software driven tree traveral.

So you can build and access arbitrarily structured HoH and still access deeply buried elements in the tree quickly.

2) The format was designed to use memory efficiently. It takes only a few hundred extra bytes over the size of an untied HoH in memory or when serialized (via Data::Dumper or Storable for example) regardless of how deep the hash is.

3) A reference to an existing HoH can be passed into Tie::ListKeyedHash->new and all of the OO key lists access methods will "just work".

 Example:

    use Tie::ListKeyedHash;

    my %hash = ( 'a' => { 'b' => 'c' } );
    my $obj = Tie::ListKeyedHash->new(\%hash);

    my $b_value = $obj->get(['a','b']);

CHANGES

 1.03 08 Oct 2020 - Relicensed under MIT License. Maintainer info updated.
                    Build configs updated. GitHub repo meta added.
                    Added 'use warnings'

 1.02 17 Sep 2005 - Extended tests to 100% coverage. Fixed bugs in 'exists'.
                    Fixed returned value for undefined values and handling
                    of setting undefined values. Miscellaneous code cleanups
                    and streamlining. Added examples to clarify what the
                    module actually does and why it is useful.

                    Extended the 'new' method to permit the efficient importing
                    of a pre-existing hash or hash reference.

 1.01 16 Sep 2005 - Restoring POD was that went missing from 1.00 upload.
                    Added META.yml to MANIFEST.
 
 1.00 15 Sep 2005 - Reorganized and clarified documentation, added build tests.
                    Fixed bug in 'exists' support.

 0.41 09 Jun 1999 - Minor documentation changes.

 0.40 04 May 1999 - Renamed to 'Tie::ListKeyedHash' after discussion on
                    comp.lang.perl.module and added (on the suggestion of
                    Ilya Zakharevich, <ilya@math.ohio-state.edu>) support
                    for using the tie hash as $hash{'key1','key2','key3'}
                    as well as its native mode of $hash{['key1','key2','key3']}

 0.20 30 Apr 1999 - Initial public release as 'Tie::ArrayHash'

METHODS

new([\%hash]);

Returns an object reference for the hash accessor.

 my $obj = Tie::ListKeyedHash->new;

You can, optionally, pass a reference to a pre-existing hash in and the returned object will provide access to its contents via the Tie::ListKeyedHash object instance.

Example:

 my %hash = ( 'a' => { 'b' => 'c' }};
 my $obj  = Tie::ListKeyedHash->new(\%hash);
clear;

Clears the entire hash.

Example:

  $obj->clear;
exists(\@key_list);

Returns true of the specified hash element exists, false if it does not. Just as with normal hashes, intermediate elements will be created if they do not already exist.

Example:

  my $key = ['a','b','c'];
  if ($obj->exists($key)) {
    # Stuff
  }
get(\@key_list);

Returns the contents of the object field denoted by the @key_list. This is a way of making arbitrary keys that act like hashes, with the 'hardwiring' requirements of hashes. The routine returns the the contents addressed by 'key1','key2','key3',...

The special case of $obj->get([]); returns a reference to the anon hash containing the hash data. This is actually a blessed reference, but you can use normal hash operators on it (such as 'keys', 'values' and 'each').

Note that returned anon hashes will not be themselves be automatically blessed into Tie::ListKeyedHash. You get back exactly whatever you stored originally. This is true of retrieving values via the tied interface as well.

Example:

  my $key = ['a','b','c'];
  my $value = $obj->get($key);
put(\@key_list, $value);

Sets $value as the contents of the object field denoted by the @key_list.

This is a way of making arbitrary keys that act like hashes, without the 'hardwiring' requirements of hashes.

Example:

  my $key = ['a','b','c'];
  $obj->put($key => 'help me');
delete(\@key_list);

Deletes the object field denoted by the @key_list.

This is a way of making arbitrary keys that act like hashes, without the 'hardwiring' requirements of hashes.

  my $key = ['a','b','c'];
  $obj->delete($key);

BUGS

None known.

TODO

Nothing planned.

AUTHORS

Jerilyn Franz <cpan@jerilyn.info>

VERSION

Version 1.03 - 2020.10.08

SEE ALSO

perl perltie

COPYRIGHT

Copyright 1999-2020 Jerilyn Franz, <cpan@jerilyn.info>. All Rights Reserved.

LICENSE

MIT License

Copyright (c) 2020 Jerilyn Franz

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

DISCLAIMER

THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

Use of this software in any way or in any form, source or binary, is not allowed in any country which prohibits disclaimers of any implied warranties of merchantability or fitness for a particular purpose or any disclaimers of a similar nature.

IN NO EVENT SHALL I BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION (INCLUDING, BUT NOT LIMITED TO, LOST PROFITS) EVEN IF I HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE