NAME

CXC::Data::Visitor - Invoke a callback on every element at every level of a data structure.

VERSION

version 0.12

SYNOPSIS

use CXC::Data::Visitor 'visit', 'RESULT_CONTINUE';

my %root = (
    fruit => {
        berry  => 'purple',
        apples => [ 'fuji', 'macoun' ],
    } );

visit(
    \%root,
    sub ( $kydx, $vref, @ ) {
        $vref->$* = 'blue' if $kydx eq 'berry';
        return RESULT_CONTINUE;
    } );

say $root{fruit}{berry}

results in

blue

DESCRIPTION

CXC::Data::Visitor::visit performs a depth-first traversal of a data structure, invoking a provided callback subroutine on elements in the structure.

Features

Overview

visit recursively traverses the container, $root, calling the passed subroutine, $callback on each element, $element, which is allowed by the "visit" option.

The traversal is depth-first, e.g. if $element is a container, $callback is called on it and then its contents before processing $element's siblings.

Each container's contents are traversed in sorted order. For hashes, this is alphabetical, for arrays, numerical. (This may be changed with the "key_sort" and "idx_sort" options).

For example, the default traversal order for the structure in the "SYNOPSIS" is

+-------------------------+-----------------------+-----+
| path                    | value                 | idx |
+-------------------------+-----------------------+-----+
| $root{fruit}            | \$root{fruit}         | 0   |
| $root{fruit}{apples}    | \$root{fruit}{apples} | 0   |
| $root{fruit}{apples}[0] | fuji                  | 0   |
| $root{fruit}{apples}[1] | macoun                | 1   |
| $root{fruit}{berry}     | purple                | 1   |
+-------------------------+-----------------------+-----+

Containers that can be reached multiple times without cycling, e.g.

%hash = ( a => { b => 1 }, );
$hash{c} = $hash{a};

are visited once per parent, e.g.

{a}, {a}{b}
{c}, {c}{b}

$callback's return value indicates how visit should proceed (see "Traversal Directives"). The simplest directive is to continue traversal; additional directives abort the traversal, abort descent into a container, revisit the current container immediately, revisit a container after its contents are visited, and other obscure combinations.

USAGE

visit has the following signature:

( $completed, $context, $metadata ) = visit( $root, $callback, %options )

The two mandatory arguments are $root, a reference to either a hash or an array, and $callback, a reference to a subroutine which will be invoked on visited elements. By default $callback is invoked on $root's elements, not on $root itself; use the "VISIT_ROOT" flag change this.

Options

visit may be passed the following options:

Callback

visit invokes $callback on selected elements of $root (see "Element Filters"). $callback is invoked as

$directive = $callback->( $kydx, $vref, $context, \%metadata );

The arguments passed to $callback are:

Traversal Directives

"$callback" must return a constant (see "EXPORTS") indicating what visit should do next. Not all constants are allowed in all contexts in which $callback is invoked; see "Calling Contexts and Allowed Traversal Directives".

Single Directives

Mixed Directives

Some directives can be mixed with "RESULT_REVISIT_CONTENTS" and "RESULT_REVISIT_ELEMENT" by performing a binary OR with them.

Calling Contexts and Allowed Traversal Directives

$callback's allowed return value depends upon the context it is called in. $callback may be called on an element multiple times during different stages of traversal.

When invoked on an element during a scan of its parent container

When invoked on a container immediately after its contents have been visited

See "RESULT_REVISIT_ELEMENT".

When invoked on $root before its contents have been visited

See "VISIT_ROOT".

When invoked on the $root immediately after its elements have been visited

See "VISIT_ROOT" and "RETURN_REVISIT_ELEMENT".

Metadata

$callback is passed a hash of state information ($metadata) kept by CXC::Data::Visitor::visit, some of which may be of interest to the callback:

$metadata has the following entries:

Element Filters

The parts of the structure that will trigger a callback. Note that by default the passed top level structure, $root is not passed to the callback. See "VISIT_ROOT".

See "EXPORTS" to import the constants.

Cycles

EXPORTS

This module uses Exporter::Tiny, which provides enhanced import utilities.

Subroutines

The following subroutine may be imported:

visit

Constants

Constants may be imported individually or as groups via tags. The available tags and their respective imported symbols are:

DEPRECATED CONSTRUCTS

SUPPORT

Bugs

Please report any bugs or feature requests to bug-cxc-data-visitor@rt.cpan.org or through the web interface at: https://rt.cpan.org/Public/Dist/Display.html?Name=CXC-Data-Visitor

Source

Source is available at

https://codeberg.org/CXC-Optics/p5-CXC-Data-Visitor

and may be cloned from

https://codeberg.org/CXC-Optics/p5-CXC-Data-Visitor.git

SEE ALSO

Please see those modules/websites for more information related to this module.

AUTHOR

Diab Jerius djerius@cpan.org

COPYRIGHT AND LICENSE

This software is Copyright (c) 2024 by Smithsonian Astrophysical Observatory.

This is free software, licensed under:

The GNU General Public License, Version 3, June 2007