NAME
Tie::Hash::MultiKey - multiple keys per value
SYNOPSIS
use Tie::Hash::MultiKey;
$thm = tie %hash, qw(Tie::Hash::MultiKey);
$thm = tied %hash;
untie %hash;
($href,$thm) = new Tie::Hash::MultiKey;
$hash{'foo'} = 'baz';
or
$hash{'foo', 'bar'} = 'baz';
or
$array_ref = ['foo', 'bar'];
$hash{ $array_ref } = 'baz';
print $hash{foo}; # prints 'baz'
print $hash{bar}; # prints 'baz'
$array_ref = ['fuz','zup'];
$val = tied(%hash)->addkey('fuz' => 'bar');
$val = tied(%hash)->addkey('fuz','zup' => 'bar');
$val = tied(%hash)->addkey( $array_ref => 'bar');
print $hash{fuz} # prints 'baz'
$array_ref = ['foo', 'bar'];
$val = tied(%hash)->remove('foo');
$val = tied(%hash)->remove('foo', 'bar');
$val = tied(%hash)->remove( $array_ref );
@ordered_keys = tied(%hash)->keylist('foo')
@allkeys_by_order = tied(%hash)->keylist();
@slotlist = tied(%hash)->slotlist($i);
$num_vals = tied(%hash)->consolidate;
($newRef,$newThm) = tied(%hash)->clone();
$newThm = tied(%hash)->copy(tied(%new));
All of the above methods can be accessed as:
i.e. $thm->consolidate;
DESCRIPTION
Tie::Hash::MultiKey creates hashes that can have multiple ordered keys
for a single value. As shown in the SYNOPSIS, multiple keys share a
common value.
Additional keys can be added that share the same value and keys can be
removed without deleting other keys that share that value.
STORE..ing a value for one or more keys that already exist will
overwrite the existing value and add any missing keys to the key group
for that value.
WARNING: multiple key values supplied as an ARRAY to STORE and DELETE
operations are passed by Perl as a single string separated by the $;
multidimensional array seperator. i.e.
$hash{'a','b','c'} = $something;
or
@keys = ('a','b','c');
$hash{@keys} = $something'
This really means $hash{join($;, 'a','b','c')};
Tie::Hash::MultiKey will do the right thing as long as your keys DO NOT
contain binary data the may include the $; separator character.
It is recommended that you use the ARRAY_REF construct to supply
multiple keys for binary data. i.e.
$hash{['a','b','c']} = $something;
or
$keys = ['a','b','c'];
$hash{$keys} = $something;
The ARRAY_REF construct is ALWAYS safe.
* $thm = tie %hash,'Tie::Hash::MultiKey';
Ties a %hash to this package for enhanced capability and returns a
method pointer.
my %hash;
my $thm = tie %hash,'Tie::Hash::MultiKey';
* $thm = tied %hash;
Returns a method pointer for this package.
* untie %hash;
Breaks the binding between a variable and this package. There is no
affect if the variable is not tied.
* ($href,$thm) = new Tie::Hash::MultiKey;
This method returns an UNBLESSED reference to an anonymous tied
%hash.
input: none
returns: unblessed tied %hash reference,
object handle
To get the object handle from \%hash use this.
$thm = tied %{$href};
In SCALAR context it returns the unblessed %hash pointer. In ARRAY
context it returns the unblessed %hash pointer and the package
object/method pointer.
* $val = $thm->addkey('new_key' => 'existing_key');
Add one or more keys to the shared key group for a particular value.
input: array or array_ref,
existing_key
returns: hash value
or dies with stack trace
Dies with stack trace if existing_key does not exist OR if new key
belongs to another key set.
Arguments may be a single SCALAR, ARRAY, or ARRAY_REF
* $val = ->remove('key');
Remove one or more keys from the shared key group for a particular
value If this operation removes the LAST key, then it performs a
DELETE which is the same as:
delete $hash{key};
remove returns a reverse list of the removed value's by key
i.e. @val = remove(something);
or $val = remove(something);
Arguments may be a single SCALAR, ARRAY or ARRAY_REF
* @ordered_keys = $thm->keylist('foo');
* @allkeys_by_order = $thm->keylist();
Returns all the keys in the group that includes the KEY 'foo' in the
order that they were added to the %hash;
If no argument is specified, returns all the keys in the %hash in
the order that they were added to the %hash
input: key or EMPTY
returns: @ordered_keys
returns: () if $key is not in the %hash
* @keys = $thm->slotlist($i);
Returns one key from each key group in position $i.
i.e.
$thm = tie %hash, 'Tie::Hash::MultiKey';
$hash{['a','b','c']} = 'one';
$hash{['d','e','f']} = 'two';
$hash{'g'} = 'three';
$hash{['h','i','j']} = 'four';
@slotkeys = $thm->slotlist(1);
will produce ('b','e', undef, 'i')
All the keys at index '1' for the groups to which they were added,
in the order which the FIRST KEY in the group was added to the
%hash. If there is no key in the specified slot, an undef is
returned for that position.
* $thm->consolidate;
USE WITH CAUTION
Consolidate all keys with the same values into common groups.
returns: number of consolidated key groups
* ($href,$thm) = $thm->clone();
This method returns an UNBLESSED reference to an anonymous tied
%hash that is a deep copy of the parent object.
input: none
returns: unblessed tied %hash reference,
object handle
To get the object handle from \%hash use this.
$thm = tied %{$href};
In SCALAR context it returns the unblessed %hash pointer. In ARRAY
context it returns the unblessed %hash pointer and the package
object/method pointer.
i.e.
$newRef = $thm->clone();
$newRref->{'a','b'} = 'content'
$newThm = tied %{$newRef};
* $new_thm = $thm->copy(tie %new,'Tie::Hash::MultiKey');
This method deep copies a MultiKey %hash to another new %hash. It
may be invoked on an existing tied object handle or a reference to a
tied %hash.
input: object handle OR reference to tied %hash
returns: object handle / method pointer
i.e
$thm = tie %hash,'Tie::Hash::MultiKey';
$newThm = $thm->copy(tie %new,'Tie::Hash::MultiKey');
or
tie %new,'Tie::Hash::MultiKey');
$newThm = $thm->copy(\%new);
NOTE: this method duplicates the data stored in the parent %hash,
overwriting and destroying anything that may have been stored in the
copy target.
COMMON OPERATIONS
A tied multikey %hash behave like a regular %hash for most operations;
$value = $hash{$key} returns the key group value
$hash{$key} = $value sets the value for the key group
i.e. all keys in the group will return that value
$hash{$key1,$key2} = $value assigns $value to the key key group
consisting of $key1, $key2 if they do not. If at least one of the keys
already exists, the remaining keys are assigned to the key group and the
value is set for the entire group.
Better syntax $hash{[$key,$key]} = $value;
delete $hash{$key} deletes the ENTIRE key group to which $key belongs.
delete $hash($key1,$key2) deletes ALL groups to which $key1 and $key2
belong.
Better syntax delete $hash{[$key1,$key2]};
keys %hash returns all keys.
values %hash returns all values
NOTE: that this will not be the same number of items as returned by keys
unless there are no key groups containing more than one key.
($k,$v) = each %hash behaves as expected.
References to tied %hash behave in the same manner as regular %hash's
except as noted for multiple key values above.
LIMITATIONS
SLICE operations will produce unusual results if you try to use regular
ARRAYS to specify key groups in the slice. Tie::Hash::MultiKey %hash's
only accept SCALAR or ARRAY_REF arguments for SLICE and direct
assigment.
i.e.
%WRONG = (
one => 1,
two => 2,
(3,4,5) => 12 # expands to 3 => 4, 5 => 12
);
%hash = ( # OK
one => 1,
two => 2,
[3,4,5] => 12
);
will produce a psuedo hash of the form:
%hash = (
one => 1,
two => 2,
3 => 12, --|
4 => 12, --|
5 => 12 --|
);
where the operation $hash{4} = 99 will change the hash to:
%hash = (
one => 1,
two => 2,
3 => 99, --|
4 => 99, --|
5 => 99 --|
);
Example: $hp = \%hash;
@{$hp}{'one','two','[3,4,5]} = (1,2,12);
produces the same result as above. If the hash already contains a KEY of
the same name, the value will be changed for all other shared keys.
--------------------------
If you are using ARRAY_REF's as keys (not as pointers to keys as above)
they must be blessed into some other package so that
ref $key ne 'ARRAY'
i.e. bless $key, 'KEY'; # or anything other than 'ARRAY'
--------------------------
Example SLICE assignments
TO tied hash
@tiedhash{@keys} = @values;
$hp = \%tiedhash;
@{$hp}{@keys} = @values;
FROM tied hash
@values = @tiedhash{@keys};
$hp = \%tiedhash;
@values = @{$hp}{@keys};
NOTE: when assigning TO the hash, keys may be ARRAY_REF's as described
above.
AUTHOR
Michael Robinton, <miker@cpan.org>
COPYRIGHT
Copyright 2014, Michael Robinton
This program is free software; you may redistribute it and/or modify it
under the same terms as Perl itself.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.