Jon Portnoy > List-Objects-WithUtils > List::Objects::WithUtils::Role::Hash



Annotate this POD


Open  0
View/Report Bugs
Module Version: 2.028003   Source  


List::Objects::WithUtils::Role::Hash - Hash manipulation methods


  ## Via List::Objects::WithUtils::Hash ->
  use List::Objects::WithUtils 'hash';

  my $hash = hash(foo => 'bar');

    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;
  with 'List::Objects::WithUtils::Role::Hash';


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


Constructs a new HASH-type object.


Creates a shallow clone of the current object.


  if ( $hash->defined($key) ) { ... }

Returns boolean true if the key has a defined value.


  if ( $hash->exists($key) ) { ... }

Returns boolean true if the key exists.


  my %hash = $hash->export;

Returns a raw key => value list.

For a plain HASH-type reference, see: "unbless"


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.


  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);

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;


The class that objects are blessed into when calling "inflate".

Defaults to List::Objects::WithUtils::Hash::Inflated.


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.


Returns boolean true if the hash has no keys.


Returns boolean true if the hash is mutable; immutable subclasses can override to provide a negative value.


The opposite of "is_mutable".


Returns a plain HASH reference (shallow clone).

Methods that manipulate the hash


Clears the current hash entirely.

Returns the (same, but now empty) hash object.



Deletes the given key(s) from the hash.

Returns an "array_type" object containing the deleted values.


    key1 => $val,
    key2 => $other,

Sets keys in the hash.

Returns the current hash object.


  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


  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.)


  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)


  # 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.


  my @keys = $hash->keys->all;

Returns the list of keys in the hash as an "array_type" object.


  my @vals = $hash->values->all;

Returns the list of values in the hash as an "array_type" object.


  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)


  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)


  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.


  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)


  # 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.)


  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.


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)


Returns a random key from the hash.

Returns undef if the hash is empty.

(Available from v2.28.1)


Returns a random value from the hash.

Returns undef if the hash is empty.

(Available from v2.28.1)


  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


  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.


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.


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__,

  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(@_) }








Jon Portnoy <>

Portions of this code are derived from Data::Perl by Matthew Phillips (CPAN: MATTP), haarg et al

Licensed under the same terms as Perl.

syntax highlighting: