NAME

    Data::DeepAccess - Access or set data in deep structures

SYNOPSIS

      use Data::DeepAccess qw(deep_exists deep_get deep_set);
    
      my %things;
      deep_set(\%things, qw(foo bar), 42);
      say $things{foo}{bar}; # 42
    
      $things{foo}{baz} = ['a'..'z'];
      say deep_get(\%things, qw(foo baz 5)); # f
    
      deep_set(\%things, qw(foo foo), undef);
      say deep_exists(\%things, qw(foo foo)); # 1
    
      deep_val(\%things, qw(bar bar)) = 'lvalue';
      say deep_val(\%things, qw(bar bar)); # lvalue

DESCRIPTION

    Provides the functions "deep_exists", "deep_get", "deep_set", and
    "deep_val" that traverse nested data structures to retrieve or set the
    value located by a list of keys.

    When traversing, keys are applied according to the type of referenced
    data structure. A hash will be traversed by hash key, an array by array
    index, and an object by method call (scalar context with no arguments).
    If the data structure is not defined, it will be traversed as a hash by
    default (but not vivified unless in a set operation).

    You can override how a key is applied, and thus what type of structure
    is vivified if necessary, by passing the key in a hashref as the value
    of key (hash) or index (array).

      deep_set(my $structure, 'foo', 42); # {foo => 42}
      deep_set(my $structure, {index => 1}, 42); # [undef, 42]
      deep_set($object, {key => 'foo'}, 42); # sets $object->{foo} directly

    For the rare case it's needed, you can also use one of the keys method
    or lvalue.

      deep_set($object, {method => 'foo'}, 42); # $object->foo(42)
      deep_set($object, {lvalue => 'foo'}, 42); # $object->foo = 42

    Attempting to traverse intermediate structures that are defined and not
    a reference to a hash, array, or object will result in an exception.

    If an object method call is the last key in a set operation or the next
    structure must be vivified, the method will be called passing the new
    value as an argument or assigned if it is treated as an lvalue.
    Attempting to call a method on an undefined value or unblessed ref in a
    set operation will result in an exception.

    Currently, undefined results from non-lvalue method calls are not
    vivified back to the object to support setting a further nested value.
    This may be supported in the future.

FUNCTIONS

    All functions are exported individually.

 deep_exists

      my $bool = deep_exists($structure, @keys);

    Returns a true value if the value exists in the referenced structure
    located by the given keys. No intermediate structures will be altered
    or vivified; a missing structure will result in a false return value.

    Array indexes are tested for existence with "exists" in perlfunc, like
    hash keys, which may have surprising results in sparse arrays. Avoid
    this situation.

    Object methods are tested for existence with $object->can($method).

    If no keys are passed, returns true.

 deep_get

      my $value = deep_get($structure, @keys);

    Retrieves the value from the referenced structure located by the given
    keys. No intermediate structures will be altered or vivified; a missing
    structure will result in undef.

    If no keys are passed, returns the original structure.

 deep_set

      $new_value = deep_set($structure, @keys, $new_value);

    Sets the value in the referenced structure located by the given keys.
    Missing intermediate structures will be vivified to hashrefs by
    default. If the structure is undefined, it must be an assignable lvalue
    to be vivified.

    If no keys are passed, the structure must be an assignable lvalue and
    will be assigned the value directly.

 deep_val

      my $value = deep_val($structure, @keys);
      deep_val($structure, @keys) = $new_value;

    Lvalue accessor that is equivalent to "deep_get" when a value is
    retrieved from it, or "deep_set" when a value is assigned to it
    (passing the assigned value as the final argument).

    The passed keys are used to traverse the structure at the time of
    retrieval or assignment, not when the function is called. This subtle
    difference may matter if the lvalue is preserved for later access, such
    as via reference.

BUGS

    Report any issues on the public bugtracker.

AUTHOR

    Dan Book <dbook@cpan.org>

CONTRIBUTORS

    Matt S Trout (mst)

COPYRIGHT AND LICENSE

    This software is Copyright (c) 2019 by Dan Book.

    This is free software, licensed under:

      The Artistic License 2.0 (GPL Compatible)

SEE ALSO

    Many prior modules for accessing specific items within a deep
    structure, which the author determined were either insufficient or
    overcomplex.

      * Hash::DeepAccess

      * Data::Deep

      * Data::Diver

      * Data::DPath

      * JSON::Pointer