.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "List::Objects::WithUtils::Role::Hash 3pm" .TH List::Objects::WithUtils::Role::Hash 3pm "2021-01-21" "perl v5.32.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" List::Objects::WithUtils::Role::Hash \- Hash manipulation methods .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 2 \& ## Via List::Objects::WithUtils::Hash \-> \& use List::Objects::WithUtils \*(Aqhash\*(Aq; \& \& my $hash = hash(foo => \*(Aqbar\*(Aq); \& \& $hash\->set( \& foo => \*(Aqbaz\*(Aq, \& pie => \*(Aqtasty\*(Aq, \& ); \& \& my @matches = $hash\->keys\->grep(sub { $_[0] =~ /foo/ })\->all; \& \& my $pie = $hash\->get(\*(Aqpie\*(Aq) \& if $hash\->exists(\*(Aqpie\*(Aq); \& \& 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 \*(AqList::Objects::WithUtils::Role::Hash\*(Aq; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" A Role::Tiny role defining methods for creating and manipulating HASH-type objects. .PP In addition to the methods documented below, these objects provide a \&\f(CW\*(C`TO_JSON\*(C'\fR method exporting a plain HASH-type reference for convenience when feeding JSON::Tiny or similar, as well as a \f(CW\*(C`TO_ZPL\*(C'\fR method for compatibility with Text::ZPL. .SS "Basic hash methods" .IX Subsection "Basic hash methods" \fInew\fR .IX Subsection "new" .PP Constructs a new HASH-type object. .PP \fIcopy\fR .IX Subsection "copy" .PP Creates a shallow clone of the current object. .PP \fIdefined\fR .IX Subsection "defined" .PP .Vb 1 \& if ( $hash\->defined($key) ) { ... } .Ve .PP Returns boolean true if the key has a defined value. .PP \fIexists\fR .IX Subsection "exists" .PP .Vb 1 \& if ( $hash\->exists($key) ) { ... } .Ve .PP Returns boolean true if the key exists. .PP \fIexport\fR .IX Subsection "export" .PP .Vb 1 \& my %hash = $hash\->export; .Ve .PP Returns a raw key => value list. .PP For a plain HASH-type reference, see: \*(L"unbless\*(R" .PP \fIarray_type\fR .IX Subsection "array_type" .PP The class name of array-type objects that will be used to contain the results of methods returning a list. .PP Defaults to List::Objects::WithUtils::Array. .PP Subclasses can override \f(CW\*(C`array_type\*(C'\fR to produce different types of array objects. .PP \fIinflate\fR .IX Subsection "inflate" .PP .Vb 2 \& my $obj = hash(foo => \*(Aqbar\*(Aq, baz => \*(Aqquux\*(Aq)\->inflate; \& my $baz = $obj\->baz; .Ve .PP Inflates the hash-type object into a simple struct-like object with accessor methods matching the keys of the hash. .PP By default, accessors are read-only; specifying \f(CW\*(C`rw =\*(C'\fR 1> allows setting new values: .PP .Vb 2 \& my $obj = hash(foo => \*(Aqbar\*(Aq, baz => \*(Aqquux\*(Aq)\->inflate(rw => 1); \& $obj\->foo(\*(Aqfrobulate\*(Aq); .Ve .PP Returns an \*(L"inflated_type\*(R" (or \*(L"inflated_rw_type\*(R") object. .PP The default objects provide a \f(CW\*(C`DEFLATE\*(C'\fR method returning a plain hash; this makes it easy to turn inflated objects back into a \f(CW\*(C`hash()\*(C'\fR for modification: .PP .Vb 2 \& my $first = hash( foo => \*(Aqbar\*(Aq, baz => \*(Aqquux\*(Aq )\->inflate; \& my $second = hash( $first\->DEFLATE, frobulate => 1 )\->inflate; .Ve .PP \fIinflated_type\fR .IX Subsection "inflated_type" .PP The class that objects are blessed into when calling \*(L"inflate\*(R". .PP Defaults to List::Objects::WithUtils::Hash::Inflated. .PP \fIinflated_rw_type\fR .IX Subsection "inflated_rw_type" .PP The class that objects are blessed into when calling \*(L"inflate\*(R" with \&\f(CW\*(C`rw =\*(C'\fR 1> specified. .PP Defaults to List::Objects::WithUtils::Hash::Inflated::RW, a subclass of List::Objects::WithUtils::Hash::Inflated. .PP \fIis_empty\fR .IX Subsection "is_empty" .PP Returns boolean true if the hash has no keys. .PP \fIis_mutable\fR .IX Subsection "is_mutable" .PP Returns boolean true if the hash is mutable; immutable subclasses can override to provide a negative value. .PP \fIis_immutable\fR .IX Subsection "is_immutable" .PP The opposite of \*(L"is_mutable\*(R". .PP \fIunbless\fR .IX Subsection "unbless" .PP Returns a plain \f(CW\*(C`HASH\*(C'\fR reference (shallow clone). .SS "Methods that manipulate the hash" .IX Subsection "Methods that manipulate the hash" \fIclear\fR .IX Subsection "clear" .PP Clears the current hash entirely. .PP Returns the (same, but now empty) hash object. .PP \fIdelete\fR .IX Subsection "delete" .PP .Vb 1 \& $hash\->delete(@keys); .Ve .PP Deletes the given key(s) from the hash. .PP Returns an \*(L"array_type\*(R" object containing the deleted values. .PP \fIset\fR .IX Subsection "set" .PP .Vb 4 \& $hash\->set( \& key1 => $val, \& key2 => $other, \& ) .Ve .PP Sets keys in the hash. .PP Returns the current hash object. .PP \fImaybe_set\fR .IX Subsection "maybe_set" .PP .Vb 3 \& 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 } .Ve .PP Like \*(L"set\*(R", but only sets values that do not already exist in the hash. .PP Returns the current hash object. .SS "Methods that retrieve items" .IX Subsection "Methods that retrieve items" \fIget\fR .IX Subsection "get" .PP .Vb 2 \& my $val = $hash\->get($key); \& my @vals = $hash\->get(@keys)\->all; .Ve .PP Retrieves a key or list of keys from the hash. .PP If taking a slice (multiple keys were specified), values are returned as an \*(L"array_type\*(R" object. (See \*(L"sliced\*(R" if you'd rather generate a new hash.) .PP \fIget_path\fR .IX Subsection "get_path" .PP .Vb 5 \& my $hash = hash( \& foo => +{ bar => +{ baz => \*(Aqbork\*(Aq } }, \& quux => [ +{ weeble => \*(Aqsnork\*(Aq } ], \& ); \& my $item = $hash\->get_path(qw/foo bar baz/); # \*(Aqbork\*(Aq .Ve .PP Attempt to retrieve a value from a 'deep' hash (without risking autovivification). .PP If an element of the given path is a (plain) array reference, as in this example: .PP .Vb 1 \& my $item = $hash\->get_path(\*(Aqquux\*(Aq, [1], \*(Aqweeble\*(Aq); # "snork" .Ve .PP \&... then it is taken as the index of an array or array-type object in the path. .PP Returns undef if any of the path elements are nonexistant. .PP 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. .PP (Available from v2.15.1) .PP \fIget_or_else\fR .IX Subsection "get_or_else" .PP .Vb 3 \& # Expect to find an array() obj at $key in $hash, \& # or create an empty one if $key doesn\*(Aqt 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) }); .Ve .PP 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. .PP 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. .PP \fIkeys\fR .IX Subsection "keys" .PP .Vb 1 \& my @keys = $hash\->keys\->all; .Ve .PP Returns the list of keys in the hash as an \*(L"array_type\*(R" object. .PP \fIvalues\fR .IX Subsection "values" .PP .Vb 1 \& my @vals = $hash\->values\->all; .Ve .PP Returns the list of values in the hash as an \*(L"array_type\*(R" object. .PP \fIinverted\fR .IX Subsection "inverted" .PP .Vb 12 \& my $hash = hash( \& a => 1, \& b => 2, \& c => 2, \& d => 3 \& ); \& my $newhash = $hash\->inverted; \& # $newhash = +{ \& # 1 => array(\*(Aqa\*(Aq), \& # 2 => array(\*(Aqb\*(Aq, \*(Aqc\*(Aq), \& # 3 => array(\*(Aqd\*(Aq), \& # } .Ve .PP Inverts the hash; the values of the original hash become keys in the new object. Their corresponding values are \*(L"array_type\*(R" objects containing the key(s) that mapped to the original value. .PP This is a bit like reversing the hash, but lossless with regards to non-unique values. .PP (Available from v2.14.1) .PP \fIiter\fR .IX Subsection "iter" .PP .Vb 4 \& my $iter = $hash\->iter; \& while (my ($key, $val) = $iter\->()) { \& # ... \& } .Ve .PP Returns an iterator that, when called, returns ($key, \f(CW$value\fR) pairs. When the list is exhausted, an empty list is returned. .PP The iterator operates on a shallow clone of the hash, making it safe to operate on the original hash while using the iterator. .PP (Available from v2.9.1) .PP \fIkv\fR .IX Subsection "kv" .PP .Vb 3 \& for my $pair ($hash\->kv\->all) { \& my ($key, $val) = @$pair; \& } .Ve .PP Returns an \*(L"array_type\*(R" object containing the key/value pairs in the hash, each of which is a two-element (unblessed) \s-1ARRAY.\s0 .PP \fIkv_grep\fR .IX Subsection "kv_grep" .PP .Vb 1 \& my $positive_vals = $hash\->kv_grep(sub { $b > 0 }); .Ve .PP Like \f(CW\*(C`grep\*(C'\fR, but operates on pairs. See \*(L"pairgrep\*(R" in List::Util. .PP Returns a hash-type object consisting of the key/value pairs for which the given block returned true. .PP (Available from v2.21.1) .PP \fIkv_map\fR .IX Subsection "kv_map" .PP .Vb 3 \& # 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) }); .Ve .PP Like \f(CW\*(C`map\*(C'\fR, but operates on pairs. See \*(L"pairmap\*(R" in List::Util. .PP Returns an \*(L"array_type\*(R" object containing the results of the map. .PP (Available from v2.8.1; in versions prior to v2.20.1, \f(CW$_[0]\fR and \f(CW$_[1]\fR must be used in place of \f(CW$a\fR and \f(CW$b\fR, respectively.) .PP \fIkv_sort\fR .IX Subsection "kv_sort" .PP .Vb 6 \& 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 .Ve .PP Like \*(L"kv\*(R", but sorted by key. A sort routine can be provided. .PP In versions prior to v2.19.1, \f(CW$_[0]\fR and \f(CW$_[1]\fR must be used in place of \&\f(CW$a\fR and \f(CW$b\fR, respectively. .PP \fIrandom_kv\fR .IX Subsection "random_kv" .PP Returns a random key/value pair from the hash as an \f(CW\*(C`ARRAY\*(C'\fR\-type reference. .PP Returns undef if the hash is empty. .PP (Available from v2.28.1) .PP \fIrandom_key\fR .IX Subsection "random_key" .PP Returns a random key from the hash. .PP Returns undef if the hash is empty. .PP (Available from v2.28.1) .PP \fIrandom_value\fR .IX Subsection "random_value" .PP Returns a random value from the hash. .PP Returns undef if the hash is empty. .PP (Available from v2.28.1) .PP \fIsliced\fR .IX Subsection "sliced" .PP .Vb 1 \& my $newhash = $hash\->sliced(@keys); .Ve .PP Returns a new hash object built from the specified set of keys and their respective values. .PP If a given key is not found in the hash, it is omitted from the result (this is different than \f(CW\*(C`perl\-5.20+\*(C'\fR hash slice syntax, which sets unknown keys to \&\f(CW\*(C`undef\*(C'\fR in the slice). .PP If you only need the values, see \*(L"get\*(R". .SS "Methods that compare hashes" .IX Subsection "Methods that compare hashes" \fIintersection\fR .IX Subsection "intersection" .PP .Vb 4 \& 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; .Ve .PP Returns the list of keys common between all given hash-type objects (including the invocant) as an \*(L"array_type\*(R" object. .PP \fIdiff\fR .IX Subsection "diff" .PP The opposite of \*(L"intersection\*(R"; returns the list of keys that are not common to all given hash-type objects (including the invocant) as an \*(L"array_type\*(R" object. .SH "NOTES FOR CONSUMERS" .IX Header "NOTES FOR CONSUMERS" If creating your own consumer of this role, some extra effort is required to make \f(CW$a\fR and \f(CW$b\fR work in sort statements without warnings; an example with a custom exported constructor might look something like: .PP .Vb 9 \& 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 = \*(Aqmyhash\*(Aq; \& sub import { \& my $pkg = caller; \& { no strict \*(Aqrefs\*(Aq; \& ${"${pkg}::a"} = ${"${pkg}::a"}; \& ${"${pkg}::b"} = ${"${pkg}::b"}; \& } \& goto &Exporter::import \& } \& \& sub myhash { _\|_PACKAGE_\|_\->new(@_) } .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" List::Objects::WithUtils .PP List::Objects::WithUtils::Hash .PP List::Objects::WithUtils::Hash::Immutable .PP List::Objects::WithUtils::Hash::Typed .PP Data::Perl .SH "AUTHOR" .IX Header "AUTHOR" Jon Portnoy .PP Portions of this code are derived from Data::Perl by Matthew Phillips (\s-1CPAN: MATTP\s0), haarg et al .PP Licensed under the same terms as Perl.