---
name: "List::Objects::WithUtils::Role::Hash"
section: "3pm"
platform: "linux"
package: "liblist-objects-withutils-perl"
version: "2.028003-5"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/List::Objects::WithUtils::Role::Hash"
---

# List::Objects::WithUtils::Role::Hash(3pm)

Hash manipulation methods

## NAME

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

## SYNOPSIS

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

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

List::Objects::WithUtils::Hash

List::Objects::WithUtils::Hash::Immutable

List::Objects::WithUtils::Hash::Typed

Data::Perl

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