NAME
Hash::AutoHash::MultiValued - Object-oriented access to hash with multi-valued elements
VERSION
Version 1.17
SYNOPSIS
# create object and set intial values
my
$mvhash
=new Hash::AutoHash::MultiValued
name
=>
'Joe'
,
hobbies
=>
'chess'
,
hobbies
=>
'cooking'
;
# access or change hash elements via methods
my
$name
=
$mvhash
->name;
# ['Joe']
my
$hobbies
=
$mvhash
->hobbies;
# ['chess','cooking']
my
@hobbies
=
$mvhash
->hobbies;
# ('chess','cooking')
$mvhash
->hobbies(
'go'
,
'rowing'
);
# new values added to existing ones
my
$hobbies
=
$mvhash
->hobbies;
# ['chess','cooking','go','rowing']
# you can also use standard hash notation and functions
my
(
$name
,
$hobbies
)=
@$mvhash
{
qw(name hobbies)
};
# get 2 elements in one statement
$mvhash
->{name}=
'Plumber'
;
# set name to ['Joe','Plumber']
my
@keys
=
keys
%$mvhash
;
# ('name','hobbies')
my
@values
=
values
%$mvhash
;
# (['Joe','Plumber'],
# ['chess','cooking','go','rowing'])
while
(
my
(
$key
,
$value
)=
each
%$mvhash
) {
"$key => @$value\n"
;
# prints each element as usual
}
delete
$mvhash
->{hobbies};
# no more hobbies
# CAUTION: hash notation doesn't respect array context!
$mvhash
->{hobbies}=(
'go'
,
'rowing'
);
# sets hobbies to last value only
my
@hobbies
=
$mvhash
->{hobbies};
# @hobbies is (['rowing'])
# alias $mvhash to regular hash for more concise hash notation
my
%hash
;
autohash_alias(
$mvhash
,
%hash
);
# access or change hash elements without using ->
$hash
{hobbies}=[
'chess'
,
'cooking'
];
# append values to hobbies
my
$name
=
$hash
{name};
# ['Joe','Plumber']
my
$hobbies
=
$hash
{hobbies};
# ['go','chess','cooking']
# another way to do the same thing
my
(
$name
,
$hobbies
)=
@hash
{
qw(name hobbies)
};
# set 'unique' in tied object to eliminate duplicates
autohash_tied(
$mvhash
)->unique(1);
$mvhash
->hobbies(
'go'
,
'cooking'
,
'rowing'
);
my
@hobbies
=
$mvhash
->hobbies;
# @hobbies is
# ('rowing','chess','cooking','go')
DESCRIPTION
This is a subclass of Hash::AutoHash which wraps a tied hash whose elements are multi-valued. It was inspired by Tie::Hash::MultiValue but differs from the original in several ways. See "DIFFERENCES FROM Tie::Hash::MultiValue" for a discussion of the differences.
Like Hash::AutoHash itself, this class lets you get or set hash elements using hash notation or by invoking a method with the same name as the key. See SYNOPSIS for examples.
Also like Hash::AutoHash, this class provides a full plate of functions for performing hash operations on Hash::AutoHash::MultiValued objects. These are useful if you want to avoid hash notation all together. The following example uses these functions to removes hash elements whose values are empty lists:
my
$mvhash
=new Hash::AutoHash::MultiValued
name
=>[],
hobbies
=>
'chess'
;
my
@keys
=autohash_keys(
$mvhash
);
for
my
$key
(
@keys
) {
autohash_delete(
$mvhash
,
$key
)
unless
defined
$mvhash
->
$key
;
}
And also like Hash::AutoHash, you can alias the object to a regular hash for more concise hash notation. See SYNOPSIS for examples. Admittedly, this is a minor convenience, but the reduction in verbosity can be useful in some cases.
As in Hash::AutoHash, the namespace is "clean"; any method invoked on an object is interpreted as a request to access or change an element of the underlying hash. The software accomplishes this by providing all its capabilities through class methods (these are methods, such as 'new', that are invoked on the class rather than on individual objects), functions that must be imported into the caller's namespace, and methods invoked on the tied object implementing the hash.
CAUTION: As of version 1.12, it is not possible to use method notation for keys with the same names as methods inherited from UNIVERSAL (the base class of everything). These are 'can', 'isa', 'DOES', and 'VERSION'. The reason is that as of Perl 5.9.3, calling UNIVERSAL methods as functions is deprecated and developers are encouraged to use method form instead. Previous versions of AutoHash are incompatible with CPAN modules that adopt this style.
Duplicate elimination and filtering
By default, hash elements may contain duplicate values.
my
$mvhash
=new Hash::AutoHash::MultiValued
hobbies
=>
'go'
,
hobbies
=>
'go'
;
my
@hobbies
=
$mvhash
->hobbies;
# ('go','go')
You can change this behavior by setting 'unique' in the tied object implementing the hash to a true value.
autohash_tied(
$mvhash
)->unique(1);
my
@hobbies
=
$mvhash
->hobbies;
# now ('go')
'unique' can be set to a boolean, as in the example, or to a subroutine (technically, a CODE ref). The subroutine should operate on two values and return true if the values are considered to be equal, and false otherwise.
By default, 'unique' is sub {my($a,$b)=@_; $a eq $b}. The following example shows how to set 'unique' to a subroutine that does case-insensitive duplicate removal.
my
$mvhash
=new Hash::AutoHash::MultiValued
hobbies
=>[
'GO'
,
'go'
];
autohash_tied(
$mvhash
)->unique(
sub
{
my
(
$a
,
$b
)=
@_
;
lc
(
$a
) eq
lc
(
$b
)});
my
@hobbies
=
$mvhash
->hobbies;
# @hobbies is ('GO')
When 'unique' is given a true value, duplicate removal occurs immediately by running all existing elements through the duplicate-removal process. Thereafter, duplicate checking occurs on every update.
In many cases, it works fine and is more efficient to perform duplicate removal on-demand rather than on every update. You can accomplish this by setting 'filter' in the tied object implementing the hash to a true value. By default, the filter function is 'uniq' from List::MoreUtils. You can change this by setting 'filter' to a subroutine reference which takes a list of values as input and returns a list of values as output. Though motivated by duplicate removal, the 'filter' function can transform the list in any way you choose.
The following contrived example shows sets 'filter' to a subroutine that performs case-independent duplicate removal and sorts the resulting values.
sub
uniq_nocase_sort {
my
%uniq
;
my
@values_lc
=
map
{
lc
(
$_
) }
@_
;
@uniq
{
@values_lc
}=
@_
;
sort
values
%uniq
;
}
my
$mvhash
=new Hash::AutoHash::MultiValued
hobbies
=>[
'GO'
,
'go'
,
'dance'
];
autohash_tied(
$mvhash
)->filter(\
&uniq_nocase_sort
);
my
@hobbies
=
$mvhash
->hobbies;
# @hobbies is ('dance','go')
You can do the same thing more concisely with this cryptic one-liner.
autohash_tied(
$mvhash
)->filter(
sub
{
my
%u
;
@u
{
map
{
lc
$_
}
@_
}=
@_
;
sort
values
%u
});
Filtering occurs when you run the 'filter' method. It does not occur on every update.
new
Title : new
Usage :
$mvhash
=new Hash::AutoHash::MultiValued
name
=>
'Joe'
,
hobbies
=>
'chess'
,
hobbies
=>
'cooking'
-- OR --
$mvhash
=new Hash::AutoHash::MultiValued
[
name
=>
'Joe'
,
hobbies
=>
'chess'
,
hobbies
=>
'cooking'
]
-- OR --
$mvhash
=new Hash::AutoHash::MultiValued
{
name
=>
'Joe'
,
hobbies
=>[
'chess'
,
'cooking'
]}
Function: Create Hash::AutoHash::MultiValued object and set elements.
Returns : Hash::AutoHash::MultiValued object
Args : Optional list of
key
=>value pairs which are used to set elements of
the object. Args can also be passed as ARRAY or HASH
Notes : Be aware
when
passing args as HASH that Perl does NOT preserve
duplicate
keys
.
unique
This method must be invoked on the tied object implementing the hash.
Title : unique
Usage :
$unique
=
tied
(
%$mvhash
)->unique
-- OR --
tied
(
%$mvhash
)->unique(
$boolean
)
-- OR --
tied
(
%$mvhash
)->unique(\
&function
)
-- OR --
$unique
=autohash_tied(
$mvhash
)->unique
-- OR --
autohash_tied(
$mvhash
)->unique(
$boolean
)
-- OR --
autohash_tied(
$mvhash
)->unique(\
&function
)
Function: Get or set option that controls duplicate elimination.
Form 1 gets the current value of the control.
Form 2. If the argument is true, duplicate-removal is turned on using
'eq'
to determine which
values
are equal.
If the argument is false, duplicate-removal is turned off.
Form 3 turns on duplicate removal using the
given
function.
autohash_tied function to get the
tied
object instead of Perl's
built-in
tied
function.
Note the
'%'
in front of
$record
in the first three forms and its
absence in the
next
three forms.
Returns : value of the control
Args : Forms 2&5. Usually a boolean value, but can be any value which is not
a CODE reference.
Forms 3&6. CODE reference
for
a function that takes two
values
and
returns true or false.
Notes : When unique is
given
a true value (including a CODE
ref
in forms 3&6)
duplicate removal occurs immediately by running all existing elements
through the duplicate-removal process. Thereafter, duplicate checking
occurs on every update.
filter
This method must be invoked on the tied object implementing the hash.
Title : filter
Usage :
$filter
=
tied
(
%$mvhash
)->filter
-- OR --
tied
(
%$mvhash
)->filter(
$boolean
)
-- OR --
tied
(
%$mvhash
)->filter(\
&function
)
-- OR --
$filter
=autohash_tied(
$mvhash
)->filter
-- OR --
autohash_tied(
$mvhash
)->filter(
$boolean
)
-- OR --
autohash_tied(
$mvhash
)->filter(\
&function
)
Function: Set function used
for
filtering and perform filtering
if
true.
Form 1 filters elements using filter function previously set.
Form 2. If true, sets the filter function to its
default
, which is
'uniq'
from L<List::MoreUtils> and performs filtering.
If false, turns filtering off.
Form 3 sets the filter function to the
given
function and performs
filtering.
autohash_tied function to get the
tied
object instead of Perl's
built-in
tied
function.
Note the
'%'
in front of
$record
in the first three forms and its
absence in the
last
three forms.
Returns : value of the control
Args : Forms 2&5. Usually a boolean value, but can be any value which is not
a CODE reference.
Forms 3&6. CODE reference
for
a function that takes a list and
returns a list. The input list is passed in
@_
.
Notes : When filter is
given
a true value (including a CODE
ref
in forms 3&6)
filtering occurs immediately by running all existing elements through
the filter function.
Functions inherited from Hash::AutoHash
The following functions are inherited from Hash::AutoHash and operate exactly as there. You must import them into your namespace before use.
qw(autohash_alias autohash_tied autohash_get autohash_set
autohash_clear autohash_delete autohash_each autohash_exists
autohash_keys autohash_values
autohash_count autohash_empty autohash_notempty)
autohash_alias
Aliasing a Hash::AutoHash::MultiValued object to a regular hash avoids the need to dereference the variable when using hash notation. As a convenience, the autoahash_alias functions can link in either direction depending on whether the given object exists.
Title : autohash_alias
Usage : autohash_alias(
$mvhash
,
%hash
)
Function: Link
$mvhash
to
%hash
such that they will have exactly the same value.
Args : Hash::AutoHash::MultiValued object and hash
Returns : Hash::AutoHash::MultiValued object
autohash_tied
You can access the object implementing the tied hash using Perl's built-in tied function or the autohash_tied function inherited from Hash::AutoHash. Advantages of autohash_tied are (1) it operates directly on the Hash::AutoHash::MultiValued object without requiring a leading '%', and (2) it provide an arguably simpler syntax for invoking methods on the tied object.
Title : autohash_tied
Usage :
$tied
=autohash_tied(
$mvhash
)
-- OR --
$tied
=autohash_tied(
%hash
)
-- OR --
$result
=autohash_tied(
$mvhash
,
'some_method'
,
@parameters
)
-- OR --
$result
=autohash_tied(
%hash
,
'some_method'
,
@parameters
)
Function: The first two forms
return
the object implementing the
tied
hash. The
latter two forms invoke a method on the
tied
object.
In forms 1 and 3, the first argument is the
Hash::AutoHash::MultiValued object.
In forms 2 and 4, the first argument is a hash to which a
Hash::AutoHash::MultiValued object
has
been aliased
Returns : In forms 1 and 2, object implementing
tied
hash or
undef
.
In forms 3 and 4, result of invoking method (which can be anything or
nothing), or
undef
.
Args : Form 1. Hash::AutoHash::MultiValued object
Form 2. hash to which Hash::AutoHash::MultiValued object is aliased
Form 3. Hash::AutoHash::MultiValued object, method name, optional
list of parameters
for
method
Form 4. hash to which Hash::AutoHash::MultiValued object is aliased,
method name, optional list of parameters
for
method
autohash_get
Title : autohash_get
Usage : (
$name
,
$hobbies
)=autohash_get(
$mvhash
,
qw(name hobbies)
)
Function: Get
values
for
multiple
keys
.
Args : Hash::AutoHash::MultiValued object and list of
keys
Returns : list of argument
values
autohash_set
Title : autohash_set
Usage : autohash_set(
$mvhash
,
name
=>
'Joe Plumber'
,
first_name
=>
'Joe'
)
-- OR --
autohash_set(
$mvhash
,[
'name'
,
'first_name'
],[
'Joe Plumber'
,
'Joe'
])
Function: Set multiple arguments in existing object.
Args : Form 1. Hash::AutoHash::MultiValued object and list of
key
=>value pairs
Form 2. Hash::AutoHash::MultiValue object, ARRAY of
keys
, ARRAY of
values
Returns : Hash::AutoHash::MultiValued object
Functions for hash-like operations
The remaining functions provide hash-like operations on Hash::AutoHash::MultiValued objects. These are useful if you want to avoid hash notation all together.
autohash_clear
Title : autohash_clear
Usage : autohash_clear(
$mvhash
)
Function: Delete entire contents of
$mvhash
Args : Hash::AutoHash::MultiValued object
Returns : nothing
autohash_delete
Title : autohash_delete
Usage : autohash_delete(
$mvhash
,
@keys
)
Function: Delete
keys
and their
values
from
$mvhash
.
Args : Hash::AutoHash::MultiValued object, list of
keys
Returns : nothing
autohash_exists
Title : autohash_exists
Usage :
if
(autohash_exists(
$mvhash
,
$key
)) { ... }
Function: Test whether key is present in
$mvhash
.
Args : Hash::AutoHash::MultiValued object, key
Returns : boolean
autohash_each
Title : autohash_each
Usage :
while
(
my
(
$key
,
$value
)=autohash_each(
$mvhash
)) { ... }
-- OR --
while
(
my
$key
=autohash_each(
$mvhash
)) { ... }
Function: Iterate over all
key
=>value pairs or all
keys
present in
$mvhash
Args : Hash::AutoHash::MultiValued object
Returns : list context:
next
key
=>value pair in
$mvhash
or empty list at end
scalar
context:
next
key in
$mvhash
or
undef
at end
autohash_keys
Title : autohash_keys
Usage :
@keys
=autohash_keys(
$mvhash
)
Function: Get all
keys
that are present in
$mvhash
Args : Hash::AutoHash::MultiValued object
Returns : list of
keys
autohash_values
Title : autohash_values
Usage :
@values
=autohash_values(
$mvhash
)
Function: Get the
values
of all
keys
that are present in
$mvhash
Args : Hash::AutoHash::MultiValued object
Returns : list of
values
autohash_count
Title : autohash_count
Usage :
$count
=autohash_count(
$mvhash
)
Function: Get the number
keys
that are present in
$mvhash
Args : Hash::AutoHash::MultiValued object
Returns : number
autohash_empty
Title : autohash_empty
Usage :
if
(autohash_empty(
$mvhash
)) { ... }
Function: Test whether
$mvhash
is empty
Args : Hash::AutoHash::MultiValued object
Returns : boolean
autohash_notempty
Title : autohash_notempty
Usage :
if
(autohash_notempty(
$mvhash
)) { ... }
Function: Test whether
$mvhash
is not empty. Complement of autohash_empty
Args : Hash::AutoHash::MultiValued object
Returns : boolean
DIFFERENCES FROM Tie::Hash::MultiValue
This class differs from Tie::Hash::MultiValue, in the following major ways:
'd' on the end of the class name
In addition to the obvious differences in class name, please note the 'd' on the end of our class name. I did it this way, because my fingers always typed it that way.
Hash::AutoHash
The many capabilities provided by Hash::AutoHash are new. This includes the ability to access hash elements using method notation.
'new' method
With our class, you construct new objects via the 'new' method, whereas in Tie::Hash::MultiValue you use 'tie'.
Setting of initial values
It is possible to set initial values when constructing the object by providing key=>value pairs to the 'new' method.
Flattening of ARRAY values
When assigning an ARRAY to an element, this class flattens the reference.
Setting of duplicate-removal function
The duplicate-removal function can be set after the fact, when the object already contains data. In Tie::Hash::MultiValue it can only be set when constructing the object.
Filtering
Filtering is a new feature.
SEE ALSO
This class was inspired by Tie::Hash::MultiValue.
perltie and Tie::Hash present background on tied hashes.
Hash::AutoHash provides the object wrapping machinery. The documentation of that class includes a detailed list of caveats and cautions. Hash::AutoHash::Args, Hash::AutoHash::AVPairsSingle, Hash::AutoHash::AVPairsMulti, Hash::AutoHash::Record are other subclasses of Hash::AutoHash.
AUTHOR
Nat Goodman, <natg at shore.net>
BUGS
Please report any bugs or feature requests to bug-hash-autohash-multivalued at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Hash-AutoHash-MultiValued. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Hash::AutoHash::MultiValued
You can also look for information at:
RT: CPAN's request tracker
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Hash-AutoHash-MultiValued
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
COPYRIGHT & LICENSE
Copyright 2009 Nat Goodman.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.