NAME

Data::Leaf::Walker - Walk the leaves of arbitrarily deep nested data structures.

VERSION

Version 0.21

SYNOPSIS

$data   = {
   a    => 'hash',
   or   => [ 'array', 'ref' ],
   with => { arbitrary => 'nesting' },
   };

$walker = Data::Leaf::Walker->new( $data );

while ( my ( $k, $v ) = $walker->each )
   {
   print "@{ $k } : $v\n";
   }
   
## output might be
## a : hash
## or 0 : array
## or 1 : ref
## with arbitrary : nesting

DESCRIPTION

Data::Leaf::Walker provides simplified access to nested data structures. It operates on key paths in place of keys. A key path is a list of HASH and ARRAY indexes which define a path through your data structure. For example, in the following data structure, the value corresponding to key path [ 0, 'foo' ] is bar:

$aoh = [ { foo => 'bar' } ];

You can get and set that value like so:

$walker = Data::Leaf::Walker->new( $aoh );      ## create the walker
$bar    = $walker->fetch( [ 0, 'foo' ] );       ## get the value 'bar'
$walker->store( [ 0, 'foo'], 'baz' );           ## change value to 'baz'

FUNCTIONS

new( $data )

Construct a new Data::Leaf::Walker instance.

$data   = {
   a    => 'hash',
   or   => [ 'array', 'ref' ],
   with => { arbitrary => 'nesting' },
   };

$walker = Data::Leaf::Walker->new( $data );

Options

  • max_depth: the each, keys and values methods iterate no deeper than max_depth keys deep.

  • min_depth: the each, keys and values methods iterate no shallower than min_depth keys deep.

each()

Iterates over the leaf values of the nested HASH or ARRAY structures. Much like the built-in each %hash function, the iterators for individual structures are global and the caller should be careful about what state they are in. Invoking the keys() or values() methods will reset the iterators. In scalar context it returns the key path only.

while ( my ( $key_path, $value ) = $walker->each )
   {
   ## do something
   }

keys()

Returns the list of all key paths.

@key_paths = $walker->keys;

values()

Returns the list of all leaf values.

@leaf_values = $walker->values;

fetch( $key_path )

Lookup the value corresponding to the given key path. If an individual key attempts to fetch from an invalid the fetch method dies.

$key_path = [ $key1, $index1, $index2, $key2 ];
$leaf     = $walker->fetch( $key_path );

store( $key_path, $value )

Set the value for the corresponding key path.

$key_path = [ $key1, $index1, $index2, $key2 ];
$walker->store( $key_path, $value );

delete( $key_path )

Delete the leaf key in the corresponding key path. Only works for a HASH leaf, dies otherwise. Returns the deleted value.

$key_path  = [ $key1, $index1, $index2, $key2 ];
$old_value = $walker->delete( $key_path );

exists( $key_path )

Returns true if the corresponding key path exists.

$key_path = [ $key1, $index1, $index2, $key2 ];
if ( $walker->exists( $key_path ) )
   {
   ## do something
   }

reset()

Resets the current iterators. This is faster than using the keys() or values() methods to do an iterator reset.

## set the max depth one above the bottom, to get the twig structures
$key_path = $walker->each;
$walker->opts( max_depth => @{ $key_path } - 1 );
$walker->reset;
@twigs = $walker->values;

opts()

Change the values of the constructor options. Only given options are affected. See new() for a description of the options. Returns the current option hash after changes are applied.

## change the max_depth
$walker->opts( max_depth => 3 );

## get the current options
%opts = $walker->opts;

AUTHOR

Dan Boorstein, <danboo at cpan.org>

CAVEATS

Global Iterators

Because the iterators are global, data structures which contain cyclical references or repeated sub structures are not handled correctly.

Hash Iterators

If you iterate directly over a hash which is also contained in your leaf walker instance, be sure to leave it in a proper state. If that hash is a sub reference within the leaf walker, calling the keys() or values() methods, for the purpose of resetting the iterator, may not be able to reach the hash. A second reset attempt should work as expected. If you consistently use the leaf walker instance to access the data structure, you should be fine.

PLANS

  • add type and twig limiters for each, keys, values

  • optional autovivification (Data::Peek, Scalar::Util, String::Numeric)

BUGS

Please report any bugs or feature requests to bug-Data-Leaf-Walker at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Data-Leaf-Walker. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Data::Leaf::Walker

You can also look for information at:

ACKNOWLEDGEMENTS

COPYRIGHT & LICENSE

Copyright 2009 Dan Boorstein.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.