项目作者: chocolateboy

项目描述 :
Flatten and unflatten nested hashrefs
高级语言: Perl
项目地址: git://github.com/chocolateboy/Hash-Fold.git
创建时间: 2014-04-16T09:53:55Z
项目社区:https://github.com/chocolateboy/Hash-Fold

开源协议:Artistic License 2.0

下载


Hash::Fold

Build Status
CPAN Version

NAME

Hash::Fold - flatten and unflatten nested hashrefs

SYNOPSIS

  1. use Hash::Fold qw(flatten unflatten);
  2. my $object = bless { foo => 'bar' };
  3. my $nested = {
  4. foo => $object,
  5. baz => {
  6. a => 'b',
  7. c => [ 'd', { e => 'f' }, 42 ],
  8. },
  9. };
  10. my $flattened = flatten($nested);
  11. is_deeply $flattened, {
  12. 'baz.a' => 'b',
  13. 'baz.c.0' => 'd',
  14. 'baz.c.1.e' => 'f',
  15. 'baz.c.2' => 42,
  16. 'foo' => $object,
  17. };
  18. my $roundtrip = unflatten($flattened);
  19. is_deeply $roundtrip, $nested;

DESCRIPTION

This module provides functional and OO interfaces which can be used to flatten,
unflatten and merge nested hashrefs.

Unless noted, the functions listed below are also available as methods. Options
provided to the Hash::Fold constructor can be supplied to the functions, e.g.:

  1. use Hash::Fold;
  2. my $folder = Hash::Fold->new(delimiter => '/');
  3. $folder->fold($hash);

is equivalent to:

  1. use Hash::Fold qw(fold);
  2. my $folded = fold($hash, delimiter => '/');

Options (and constructor args) can be supplied as a list of key/value pairs or
a hashref, so the following are equivalent:

  1. my $folded = fold($hash, delimiter => '/' );
  2. my $folded = fold($hash, { delimiter => '/' });

In addition, Hash::Fold uses
Sub::Exporter, which allows functions
to be imported with options baked in, e.g.:

  1. use Hash::Fold fold => { delimiter => '/' };
  2. my $folded = fold($hash);

OPTIONS

As described above, the following options can be supplied as constructor args,
import args, or per-function overrides. Under the hood, they are
(Moo) attributes which can be wrapped and
overridden like any other attributes.

array_delimiter

Type: Str, ro, default: “.”

The delimiter prefixed to array elements when flattening and unflattening.

hash_delimiter

Type: Str, ro, default: “.”

The delimiter prefixed to hash elements when flattening and unflattening.

delimiter

Type: Str

This is effectively a write-only attribute which assigns the same string to
array_delimiter and hash_delimiter.
It can only be supplied as a constructor arg or function option (which are
equivalent) i.e. Hash::Fold instances have no delimiter method.

on_cycle

Type: (Hash::Fold, Ref) → None, ro

A callback invoked whenever fold encounters a circular reference
i.e. a reference which contains itself as a nested value.

The callback is passed two arguments: the Hash::Fold instance and the value, e.g.:

  1. sub on_cycle {
  2. my ($folder, $value) = @_;
  3. warn 'self-reference found: ', Dumper(value), $/;
  4. }
  5. my $folder = Hash::Fold->new(on_cycle => \&on_cycle);

Note that circular references are handled correctly i.e. they are treated as
terminals and not traversed. This callback merely provides a mechanism to
report them (e.g. by issuing a warning).

The default callback does nothing.

on_object

Type: (Hash::Fold, Ref) → Any, ro

A callback invoked whenever fold encounters a value for which the
is_object method returns true i.e. any reference that isn’t an
unblessed arrayref or unblessed hashref. This callback can be used to modify
the value, e.g. to return a traversable value (e.g. unblessed hashref) in place
of a terminal (e.g. blessed hashref).

The callback is passed two arguments: the Hash::Fold instance and the object,
e.g.:

  1. use Scalar::Util qw(blessed);
  2. sub on_object {
  3. my ($folder, $value) = @_;
  4. if (blessed($value) && $value->isa('HASH')) {
  5. return { %$value }; # unbless
  6. } else {
  7. return $value;
  8. }
  9. }
  10. my $folder = Hash::Fold->new(on_object => \&on_object);

The default callback returns its value unchanged.

EXPORTS

Nothing by default. The following functions can be imported.

fold

Signature: (HashRef [, Hash|HashRef ]) → HashRef

Takes a nested hashref and returns a single-level hashref with (by default)
dotted keys. The delimiter can be overridden via the delimiter,
array_delimiter and hash_delimiter
options.

Unblessed arrayrefs and unblessed hashrefs are traversed. All other values
(e.g. strings, regexps, objects etc.) are treated as terminals and passed
through verbatim, although this can be overridden by supplying a suitable
on_object callback.

flatten

Signature: (HashRef [, Hash|HashRef ]) → HashRef

Provided as an alias for fold.

unfold

Signature: (HashRef [, Hash|HashRef ]) → HashRef

Takes a flattened hashref and returns the corresponding nested hashref.

unflatten

Signature: (HashRef [, Hash|HashRef ]) → HashRef

Provided as an alias for unfold.

merge

Signature: (HashRef [, HashRef… ]) → HashRef

Signature: (ArrayRef\ [, Hash|HashRef ]) → HashRef

Takes a list of hashrefs which are then flattened, merged into one (in the
order provided i.e. with precedence given to the rightmost arguments) and
unflattened i.e. shorthand for:

  1. unflatten { map { %{ flatten $_ } } @_ }

To provide options to the merge subroutine, pass the hashrefs in an arrayref,
and the options (as usual) as a list of key/value pairs or a hashref:

  1. merge([ $hash1, $hash2, ... ], delimiter => ... )
  2. merge([ $hash1, $hash2, ... ], { delimiter => ... })

METHODS

is_object

Signature: Any → Bool

This method is called from fold to determine whether a value should
be passed to the on_object callback.

It is passed each value encountered while traversing a hashref and returns true
for all references (e.g. regexps, globs, objects etc.) apart from unblessed
arrayrefs and unblessed hashrefs, and false for all other values (i.e.
unblessed hashrefs, unblessed arrayrefs, and non-references).

VERSION

1.0.0

SEE ALSO

AUTHORS

COPYRIGHT

Copyright © 2014-2021 by chocolateboy.

This is free software; you can redistribute it and/or modify it under the
terms of the Artistic License 2.0.