NAME
List::Objects::WithUtils::Role::Hash - Hash manipulation methods
SYNOPSIS
## Via List::Objects::WithUtils::Hash ->
my
$hash
= hash(
foo
=>
'bar'
);
$hash
->set(
foo
=>
'baz'
,
pie
=>
'tasty'
,
);
my
@matches
=
$hash
->
keys
->
grep
(
sub
{
$_
[0] =~ /foo/ })->all;
my
$pie
=
$hash
->get(
'pie'
)
if
$hash
->
exists
(
'pie'
);
for
my
$pair
(
$hash
->kv->all ) {
my
(
$key
,
$val
) =
@$pair
;
...
}
my
$obj
=
$hash
->inflate;
my
$foo
=
$obj
->foo;
## As a Role ->
use
Role::Tiny::With;
DESCRIPTION
A Role::Tiny role defining methods for creating and manipulating HASH-type objects.
In addition to the methods documented below, these objects provide a TO_JSON
method exporting a plain HASH-type reference for convenience when feeding JSON::Tiny or similar, as well as a TO_ZPL
method for compatibility with Text::ZPL.
Basic hash methods
new
Constructs a new HASH-type object.
copy
Creates a shallow clone of the current object.
defined
if
(
$hash
->
defined
(
$key
) ) { ... }
Returns boolean true if the key has a defined value.
exists
if
(
$hash
->
exists
(
$key
) ) { ... }
Returns boolean true if the key exists.
export
my
%hash
=
$hash
->export;
Returns a raw key => value list.
For a plain HASH-type reference, see: "unbless"
array_type
The class name of array-type objects that will be used to contain the results of methods returning a list.
Defaults to List::Objects::WithUtils::Array.
Subclasses can override array_type
to produce different types of array objects.
inflate
my
$obj
= hash(
foo
=>
'bar'
,
baz
=>
'quux'
)->inflate;
my
$baz
=
$obj
->baz;
Inflates the hash-type object into a simple struct-like object with accessor methods matching the keys of the hash.
By default, accessors are read-only; specifying rw =
1> allows setting new values:
my
$obj
= hash(
foo
=>
'bar'
,
baz
=>
'quux'
)->inflate(
rw
=> 1);
$obj
->foo(
'frobulate'
);
Returns an "inflated_type" (or "inflated_rw_type") object.
The default objects provide a DEFLATE
method returning a plain hash; this makes it easy to turn inflated objects back into a hash()
for modification:
my
$first
= hash(
foo
=>
'bar'
,
baz
=>
'quux'
)->inflate;
my
$second
= hash(
$first
->DEFLATE,
frobulate
=> 1 )->inflate;
inflated_type
The class that objects are blessed into when calling "inflate".
Defaults to List::Objects::WithUtils::Hash::Inflated.
inflated_rw_type
The class that objects are blessed into when calling "inflate" with rw =
1> specified.
Defaults to List::Objects::WithUtils::Hash::Inflated::RW, a subclass of List::Objects::WithUtils::Hash::Inflated.
is_empty
Returns boolean true if the hash has no keys.
is_mutable
Returns boolean true if the hash is mutable; immutable subclasses can override to provide a negative value.
is_immutable
The opposite of "is_mutable".
unbless
Returns a plain HASH
reference (shallow clone).
Methods that manipulate the hash
clear
Clears the current hash entirely.
Returns the (same, but now empty) hash object.
delete
$hash
->
delete
(
@keys
);
Deletes the given key(s) from the hash.
Returns an "array_type" object containing the deleted values.
set
$hash
->set(
key1
=>
$val
,
key2
=>
$other
,
)
Sets keys in the hash.
Returns the current hash object.
maybe_set
my
$hash
= hash(
foo
=> 1,
bar
=> 2,
baz
=> 3);
$hash
->maybe_set(
foo
=> 2,
bar
=> 3,
quux
=> 4);
# $hash = +{ foo => 1, bar => 2, baz => 3, quux => 4 }
Like "set", but only sets values that do not already exist in the hash.
Returns the current hash object.
Methods that retrieve items
get
my
$val
=
$hash
->get(
$key
);
my
@vals
=
$hash
->get(
@keys
)->all;
Retrieves a key or list of keys from the hash.
If taking a slice (multiple keys were specified), values are returned as an "array_type" object. (See "sliced" if you'd rather generate a new hash.)
get_path
my
$hash
= hash(
foo
=> +{
bar
=> +{
baz
=>
'bork'
} },
quux
=> [ +{
weeble
=>
'snork'
} ],
);
my
$item
=
$hash
->get_path(
qw/foo bar baz/
);
# 'bork'
Attempt to retrieve a value from a 'deep' hash (without risking autovivification).
If an element of the given path is a (plain) array reference, as in this example:
my
$item
=
$hash
->get_path(
'quux'
, [1],
'weeble'
);
# "snork"
... then it is taken as the index of an array or array-type object in the path.
Returns undef if any of the path elements are nonexistant.
An exception is thrown if an invalid access is attempted, such as trying to use a hash-type object as if it were an array.
(Available from v2.15.1)
get_or_else
# Expect to find an array() obj at $key in $hash,
# or create an empty one if $key doesn't exist:
my
@all
=
$hash
->get_or_else(
$key
=> array)->all;
# Or pass a coderef
# First arg is the object being operated on
# Second arg is the requested key
my
$item
=
$hash
->get_or_else(
$key
=>
sub
{
shift
->get(
$defaultkey
) });
Retrieves a key from the hash; optionally takes a second argument that is used as a default value if the given key does not exist in the hash.
If the second argument is a coderef, it is invoked on the object (with the requested key as an argument) and its return value is taken as the default value.
keys
my
@keys
=
$hash
->
keys
->all;
Returns the list of keys in the hash as an "array_type" object.
values
my
@vals
=
$hash
->
values
->all;
Returns the list of values in the hash as an "array_type" object.
inverted
my
$hash
= hash(
a
=> 1,
b
=> 2,
c
=> 2,
d
=> 3
);
my
$newhash
=
$hash
->inverted;
# $newhash = +{
# 1 => array('a'),
# 2 => array('b', 'c'),
# 3 => array('d'),
# }
Inverts the hash; the values of the original hash become keys in the new object. Their corresponding values are "array_type" objects containing the key(s) that mapped to the original value.
This is a bit like reversing the hash, but lossless with regards to non-unique values.
(Available from v2.14.1)
iter
my
$iter
=
$hash
->iter;
while
(
my
(
$key
,
$val
) =
$iter
->()) {
# ...
}
Returns an iterator that, when called, returns ($key, $value) pairs. When the list is exhausted, an empty list is returned.
The iterator operates on a shallow clone of the hash, making it safe to operate on the original hash while using the iterator.
(Available from v2.9.1)
kv
for
my
$pair
(
$hash
->kv->all) {
my
(
$key
,
$val
) =
@$pair
;
}
Returns an "array_type" object containing the key/value pairs in the hash, each of which is a two-element (unblessed) ARRAY.
kv_grep
my
$positive_vals
=
$hash
->kv_grep(
sub
{
$b
> 0 });
Like grep
, but operates on pairs. See "pairgrep" in List::Util.
Returns a hash-type object consisting of the key/value pairs for which the given block returned true.
(Available from v2.21.1)
kv_map
# Add 1 to each value, get back an array-type object:
my
$kvs
= hash(
a
=> 2,
b
=> 2,
c
=> 3)
->kv_map(
sub
{ (
$a
,
$b
+ 1) });
Like map
, but operates on pairs. See "pairmap" in List::Util.
Returns an "array_type" object containing the results of the map.
(Available from v2.8.1; in versions prior to v2.20.1, $_[0]
and $_[1]
must be used in place of $a
and $b
, respectively.)
kv_sort
my
$kvs
= hash(
a
=> 1,
b
=> 2,
c
=> 3)->kv_sort;
# $kvs = array(
# [ a => 1 ],
# [ b => 2 ],
# [ c => 3 ]
# )
my
$reversed
= hash(
a
=> 1,
b
=> 2,
c
=> 3)
->kv_sort(
sub
{
$b
cmp
$a
});
# Reverse result as above
Like "kv", but sorted by key. A sort routine can be provided.
In versions prior to v2.19.1, $_[0]
and $_[1]
must be used in place of $a
and $b
, respectively.
random_kv
Returns a random key/value pair from the hash as an ARRAY
-type reference.
Returns undef if the hash is empty.
(Available from v2.28.1)
random_key
Returns a random key from the hash.
Returns undef if the hash is empty.
(Available from v2.28.1)
random_value
Returns a random value from the hash.
Returns undef if the hash is empty.
(Available from v2.28.1)
sliced
my
$newhash
=
$hash
->sliced(
@keys
);
Returns a new hash object built from the specified set of keys and their respective values.
If a given key is not found in the hash, it is omitted from the result (this is different than perl-5.20+
hash slice syntax, which sets unknown keys to undef
in the slice).
If you only need the values, see "get".
Methods that compare hashes
intersection
my
$first
= hash(
a
=> 1,
b
=> 2,
c
=> 3);
my
$second
= hash(
b
=> 2,
c
=> 3,
d
=> 4);
my
$intersection
=
$first
->intersection(
$second
);
my
@common
=
$intersection
->
sort
->all;
Returns the list of keys common between all given hash-type objects (including the invocant) as an "array_type" object.
diff
The opposite of "intersection"; returns the list of keys that are not common to all given hash-type objects (including the invocant) as an "array_type" object.
NOTES FOR CONSUMERS
If creating your own consumer of this role, some extra effort is required to make $a
and $b
work in sort statements without warnings; an example with a custom exported constructor might look something like:
package
My::Custom::Hash;
use
strictures 2;
require
Role::Tiny;
Role::Tiny->apply_roles_to_package( __PACKAGE__,
qw/
List::Objects::WithUtils::Role::Hash
My::Custom::Hash::Role
/
);
use
Exporter ();
our
@EXPORT
=
'myhash'
;
sub
import
{
my
$pkg
=
caller
;
{
no
strict
'refs'
;
${
"${pkg}::a"
} = ${
"${pkg}::a"
};
${
"${pkg}::b"
} = ${
"${pkg}::b"
};
}
goto
&Exporter::import
}
sub
myhash { __PACKAGE__->new(
@_
) }
SEE ALSO
List::Objects::WithUtils::Hash
List::Objects::WithUtils::Hash::Immutable
List::Objects::WithUtils::Hash::Typed
AUTHOR
Jon Portnoy <avenj@cobaltirc.org>
Portions of this code are derived from Data::Perl by Matthew Phillips (CPAN: MATTP), haarg et al
Licensed under the same terms as Perl.