.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is turned on, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{
. if \nF \{
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "Data::Walk 3pm"
.TH Data::Walk 3pm "2016-08-02" "perl v5.22.2" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
Data::Walk \- Traverse Perl data structures
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 2
\& use Data::Walk;
\& walk \e&wanted, @items_to_walk;
\&
\& use Data::Walk;
\& walkdepth \e&wanted, @items_to_walk;
\&
\& use Data::Walk;
\& walk { wanted => \e&process, follow => 1 }, $self;
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
The above synopsis bears an amazing similarity to \fIFile::Find\fR\|(3pm)
and this is not coincidental.
.PP
\&\fIData::Walk\fR\|(3pm) is for data what \fIFile::Find\fR\|(3pm) is for files.
You can use it for rolling your own serialization class, for displaying
Perl data structures, for deep copying or comparing, for recursive
deletion of data, or ...
.PP
If you are impatient and already familiar with \fIFile::Find\fR\|(3pm),
you can skip the following documentation and proceed with
\&\*(L"\s-1DIFFERENCES TO FILE::FIND\*(R"\s0.
.SH "FUNCTIONS"
.IX Header "FUNCTIONS"
The module exports two functions by default:
.IP "\fBwalk\fR" 4
.IX Item "walk"
.Vb 2
\& walk \e&wanted, @items;
\& walk \e%options, @items;
.Ve
.Sp
As the name suggests, the function traverses the items in the order
they are given. For every object visited, it calls the &wanted
subroutine. See \*(L"\s-1THE WANTED FUNCTION\*(R"\s0 for details.
.IP "\fBwalkdepth\fR" 4
.IX Item "walkdepth"
.Vb 2
\& walkdepth \e&wanted, @items;
\& walkdepth \e%options, @items;
.Ve
.Sp
Works exactly like \f(CW\*(C`walk()\*(C'\fR but it first descends deeper into
the structure, before visiting the nodes on the current level.
If you want to delete visited nodes, then \f(CW\*(C`walkdepth()\*(C'\fR is probably
your friend.
.SH "OPTIONS"
.IX Header "OPTIONS"
The first argument to \f(CW\*(C`walk()\*(C'\fR and \f(CW\*(C`walkdepth()\*(C'\fR is either a
code reference to your &wanted function, or a hash reference
describing the operations to be performed for each visited
node.
.PP
Here are the possible keys for the hash.
.IP "\fBwanted\fR" 4
.IX Item "wanted"
The value should be a code reference. This code reference is
described in \*(L"\s-1THE WANTED FUNCTION\*(R"\s0 below.
.IP "\fBbydepth\fR" 4
.IX Item "bydepth"
Visits nodes on the current level of recursion only \fBafter\fR
descending into subnotes. The entry point \f(CW\*(C`walkdepth()\*(C'\fR is
a shortcut for specifying \f(CW\*(C`{ bydepth => 1 }\*(C'\fR.
.IP "\fBpreprocess\fR" 4
.IX Item "preprocess"
The value should be a code reference. This code reference is used
to preprocess the current node \f(CW$Data::Walk::container\fR. Your
preprocessing function is called before the loop that calls the
\&\f(CW\*(C`wanted()\*(C'\fR function. It is called with a list of member nodes
and is expected to return such a list. The list will contain
all sub-nodes, regardless of the value of the option \fIfollow\fR!
The list is a shallow copy of the data contained in the original
structure. You can therefore safely delete items in it, without
affecting the original data.
.Sp
The behavior is identical for regular arrays and hashes, so you
probably want to coerce the list passed as an argument into a hash
then. The variable \f(CW$Data::Walk::type\fR will contain the string
\&\*(L"\s-1HASH\*(R"\s0 if the currently inspected node is a hash.
.Sp
You can use the preprocessing function to sort the items
contained or to filter out unwanted items. The order is also preserved
for hashes!
.IP "\fBpreprocess_hash\fR" 4
.IX Item "preprocess_hash"
The value should be a code reference. The code is executed
right after an eventual \fIpreprocess_hash\fR handler, but only
if the current container is a hash. It is skipped for regular
arrays.
.Sp
You will usually prefer a \fIpreprocess_hash\fR handler over a
\&\fIpreprocess\fR handler if you only want to sort hash keys.
.IP "\fBpostprocess\fR" 4
.IX Item "postprocess"
The value should be a code reference. It is invoked just before
leaving the currently visited node. It is called in void context
with no arguments. The variable \f(CW$Data::Walk::container\fR points
to the currently visited node.
.IP "\fBfollow\fR" 4
.IX Item "follow"
Causes cyclic references to be followed. Normally, the traversal
will not descend into nodes that have already been visited. If
you set the option \fIfollow\fR to a truth value, you can change this
behavior. Unless you take additional measures, this will always
imply an infinite loop!
.Sp
Please note that the &wanted function is also called for nodes
that have already been visited! The effect of \fIfollow\fR is to
suppress descending into subnodes.
.PP
All other options are silently ignored.
.SH "THE WANTED FUNCTION"
.IX Header "THE WANTED FUNCTION"
The &wanted function does whatever verifications you want on each
item in the data structure. Note that despite its name, the &wanted
function is a generic callback and does \fBnot\fR tell \fIData::Walk\fR\|(3pm)
if an item is \*(L"wanted\*(R" or not. In fact, its return value is
ignored.
.PP
The wanted function takes no arguments but rather does its work
through a collection of variables:
.ie n .IP "\fB\fB$_\fB\fR" 4
.el .IP "\fB\f(CB$_\fB\fR" 4
.IX Item "$_"
The currently visited node. Think \*(L"file\*(R" in terms of \fIFile::Find\fR\|(3pm)!
.ie n .IP "\fB\fB$Data::Walk::container\fB\fR" 4
.el .IP "\fB\f(CB$Data::Walk::container\fB\fR" 4
.IX Item "$Data::Walk::container"
The node containing the currently visited node, either a reference to
a hash or an array. Think \*(L"directory\*(R" in terms of \fIFile::Find\fR\|(3pm)!
.ie n .IP "\fB\fB$Data::Walk::type\fB\fR" 4
.el .IP "\fB\f(CB$Data::Walk::type\fB\fR" 4
.IX Item "$Data::Walk::type"
The base type of the object that \f(CW$Data::Walk::container\fR
references. This is either \*(L"\s-1ARRAY\*(R"\s0 or \*(L"\s-1HASH\*(R"\s0 or the empty string for
everything else.
.ie n .IP "\fB\fB$Data::Walk::seen\fB\fR" 4
.el .IP "\fB\f(CB$Data::Walk::seen\fB\fR" 4
.IX Item "$Data::Walk::seen"
For references, this will hold the number of times the currently
visited node has been visited \fIbefore\fR. The value is consequently
set to 0 not 1 on the first visit. For non-references, the value
is undefined.
.ie n .IP "\fB\fB$Data::Walk::address\fB\fR" 4
.el .IP "\fB\f(CB$Data::Walk::address\fB\fR" 4
.IX Item "$Data::Walk::address"
For references, this will hold the memory address it points to. It
can be used as a unique identifier for the current node. For non\-
references, the value is undefined.
.ie n .IP "\fB\fB$Data::Walk::depth\fB\fR" 4
.el .IP "\fB\f(CB$Data::Walk::depth\fB\fR" 4
.IX Item "$Data::Walk::depth"
The depth of the current recursion.
.ie n .IP "\fB\fB$Data::Walk::index\fB\fR" 4
.el .IP "\fB\f(CB$Data::Walk::index\fB\fR" 4
.IX Item "$Data::Walk::index"
Holds the index of the current item in the container. Note that hashes
and arrays are treated the same. Therefore, if the current container is
a hash and \fB\f(CB$Data::Walk::index\fB\fR is even then \fB\f(CB$_\fB\fR is a hash key. If
it is odd, then \fB\f(CB$_\fB\fR is a hash value.
.Sp
Note that the root container is the array of items to search that you
passed to the wanted function!
.Sp
This variable has been added in Data::Walk version 1.01.
.PP
These variables should not be modified.
.SH "DIFFERENCES TO FILE::FIND"
.IX Header "DIFFERENCES TO FILE::FIND"
The \s-1API\s0 of \fIData::Walk\fR\|(3pm) tries to mimic the \s-1API\s0 of \fIFile::Find\fR\|(3pm)
to a certain extent. If you are already familiar with \fIFile::Find\fR\|(3pm)
you will find it very easy to use \fIData::Walk\fR\|(3pm). Even the
documentation for \fIData::Walk\fR\|(3pm) is in parts similar or identcal
to that of \fIFile::Find\fR\|(3pm).
.SS "Analogies"
.IX Subsection "Analogies"
The equivalent of directories in \fIFile::Find\fR\|(3pm) are the container
data types in \fIData::Walk\fR\|(3pm). Container data types are arrays
(aka lists) and associative arrays (aka hashes). Files are equivalent
to scalars. Wherever \fIFile::Find\fR\|(3pm) passes lists of strings to functions,
\&\fIData::Walk\fR\|(3pm) passes lists of variables.
.SS "Function Names"
.IX Subsection "Function Names"
Instead of \f(CW\*(C`find()\*(C'\fR and \f(CW\*(C`finddepth()\*(C'\fR, \fIData::Walk\fR\|(3pm) uses
\&\f(CW\*(C`walk()\*(C'\fR and \f(CW\*(C`walkdepth()\*(C'\fR, like the smart reader
has already guessed after reading the \*(L"\s-1SYNOPSIS\*(R"\s0.
.SS "Variables"
.IX Subsection "Variables"
The variable \f(CW$Data::Walk::container\fR is vaguely equivalent to
\&\f(CW$File::Find::dir\fR. All other variables are specific to the
corresponding module.
.SS "Wanted Function"
.IX Subsection "Wanted Function"
Like its archetype from \fIFile::Find\fR\|(3pm), the wanted function of
\&\fIData::Walk\fR\|(3pm) is called with \f(CW$_\fR set to the currently inspected
item.
.SS "Options"
.IX Subsection "Options"
The option \fIfollow\fR has the effect that \fIData::Walk\fR\|(3pm) also
descends into nodes it has already visited. Unless you take
extra measures, this will lead to an infinite loop!
.PP
A number of options are not applicable to data traversion and
are ignored by \fIData::Walk\fR\|(3pm). Examples are \fIfollow_fast\fR,
\&\fIfollow_skip\fR, \fIno_chdir\fR, \fIuntaint\fR, \fIuntaint_pattern\fR, and
\&\fIuntaint_skip\fR. To give truth the honor, all unrecognized options
are skipped.
.SH "EXAMPLES"
.IX Header "EXAMPLES"
Following are some recipes for common tasks.
.SS "Recurse To Maximum Depth"
.IX Subsection "Recurse To Maximum Depth"
If you want to stop the recursion at a certain level, do it as follows:
.PP
.Vb 12
\& my $max_depth = 20;
\& sub not_too_deep {
\& if ($Data::Walk::depth > $max_depth) {
\& return ();
\& } else {
\& return @_;
\& }
\& }
\& sub do_something1 {
\& # Your code goes here.
\& }
\& walk { wanted => \e&do_something, preprocess => \e¬_too_deep };
.Ve
.SH "BUGS"
.IX Header "BUGS"
If you think you have spotted a bug, you can share it with others in the
bug tracking system at http://rt.cpan.org/NoAuth/Bugs.html?Dist=Data\-Walk.
.SH "COPYING"
.IX Header "COPYING"
Copyright (C) 2005\-2016 Guido Flohr ,
, all rights reserved.
.PP
This program is free software; you can redistribute it and/or modify it
under the terms of the \s-1GNU\s0 Library General Public License as published
by the Free Software Foundation; either version 2, or (at your option)
any later version.
.PP
This program is distributed in the hope that it will be useful,
but \s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of
\&\s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE. \s0 See the \s-1GNU\s0
Library General Public License for more details.
.PP
You should have received a copy of the \s-1GNU\s0 Library General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place \- Suite 330, Boston, \s-1MA 02111\-1307,
USA.\s0
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fIData::Dumper\fR\|(3pm), \fIStorable\fR\|(3pm), \fIFile::Find\fR\|(3pm), \fIperl\fR\|(1)