The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


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


Version 0.21


   $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


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'


new( $data )

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

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

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


  • 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.


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


Returns the list of all key paths.

   @key_paths = $walker->keys;


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


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 );
   @twigs = $walker->values;


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;


Dan Boorstein, <danboo at>


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.


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

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


Please report any bugs or feature requests to bug-Data-Leaf-Walker at, or through the web interface at I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.


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

    perldoc Data::Leaf::Walker

You can also look for information at:



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 for more information.