-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathREADME
More file actions
204 lines (144 loc) · 5.53 KB
/
README
File metadata and controls
204 lines (144 loc) · 5.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
NAME
Data::Dmap - just like map, but on deep data structures
VERSION
Version 0.07.
SYNOPSIS
This module provides the single function "dmap" which carries out a
"map"-like operation on deep data structures.
use Data::Dmap;
my $foo = {
cars => [ 'ford', 'opel', 'BMW' ],
birds => [ 'cuckatoo', 'ostrich', 'frigate' ],
handler => sub { print "barf\n" }
};
# This removes all keys named 'cars'
my($bar) = dmap { delete $_->{cars} if ref eq 'HASH'; $_ } $foo;
# This replaces arrays with the number of elements they contains
my($other) = dmap { $_ = scalar @$_ if ref eq 'ARRAY'; $_ } $foo;
use Data::Dumper;
print Dumper $other;
#
# Prints
# {
# birds => 3,
# handler => sub { "DUMMY" }
# }
# (Data::Dumper doesn't dump subs)
$other->{handler}->();
# Prints
# barf
EXPORTS
"dmap" (always exported) - the dmap function that does deep in-place
mapping
"cut" (optional) - a function for stopping recursion.
SUBROUTINES
"dmap"
This function works like "map" - it takes an expression followed by a
list, evaluates the expression on each member of the list and returns
the result.
The only difference is that any references returned by the expression
will also be traversed and passed to the expression once again, thus
making it possible to make deep traversal of any data structure.
Objects (references blessed to something) are just traversed as if they
weren't blessed.
Examples
Delete all hash references
use Data::Dmap;
use Data::Dump 'pp';
pp dmap { return $_ unless ref eq 'HASH'; return; } 1, 'foo', [ { a => 1 }, 2];
# Prints:
# (1, "foo", [2])
Delete every odd number
use Data::Dmap;
use Data::Dump 'pp';
pp dmap { return if $_ % 2; $_ } [ 1 .. 10 ];
# Prints:
# [2, 4, 6, 8, 10]
Replace all hash refs with some $object of class "thingy".
use Data::Dmap;
use Data::Dump 'pp';
pp dmap { return bless $_, 'thingy' if ref eq 'HASH'; $_ } [ 1, "hello", { a => 1 } ];
# Prints:
# [1, "hello", bless({ a => 1 }, "thingy")]
"dmap" understands what you want, if you return nothing (as opposed to
"undef") when evaluating the expression for a hash key:
use Data::Dmap;
use Data::Dump 'pp;
my $characters = { main => 'pooh', secondary => 'piglet' };
pp dmap { return if $_ eq "piglet"; $_ } $characters;
# Prints:
# { main => "pooh" }
Because the output from the expression is being traversed, you can use
"dmap" to generate data structures:
use Data::Dmap;
use Data::Dump 'pp';
my $height = 3;
pp dmap { if(ref eq 'HASH' and $height--) { $_->{a} = {height => $height} } $_ } {};
# Prints:
# {
# a => {
# a => {
# a => {
# height => 0
# },
# height => 1
# },
# height => 2
# }
# }
# (My own formatting above.)
"cut"
The "cut" routine stops recursion at any point and returns any data as
it is in place of the current node.
Examples
use Data::Dmap 'cut';
use Data::Dump 'pp';
my $deep = {
level => 1,
data => {
level => 2,
data => {
level => 3
}
}
};
pp dmap { cut('stop') if ref eq 'HASH' and $_->{level} == 2} $deep;
# Prints:
#
# { data => { data => "stop", level => 2 }, level => 1 }
AUTHOR
Michael Zedeler, "<michael@zedeler.dk>"
BUGS
If you find a bug, please consider helping to fix the bug by doing this:
* Fork "Data::Dmap" from <http://github.com/mzedeler/Data-Dmap>
* Write a test case in the "t" directory, commit and push it.
* Fix the bug or (if you don't know how to fix it), report the bug
Bugs and feature requests can be reported through the web interface at
<http://github.com/mzedeler/Data-Dmap/issues>. I may not be notified, so
send me a mail too.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Data::Dmap
You can also look for information at:
* The github issue tracker
<http://github.com/mzedeler/Data-Dmap/issues>
* AnnoCPAN: Annotated CPAN documentation
<http://annocpan.org/dist/Data-Dmap>
* CPAN Ratings
<http://cpanratings.perl.org/d/Data-Dmap>
* Search CPAN
<http://search.cpan.org/dist/Data-Dmap/>
SEE ALSO
Data::Rmap, Data::Visitor, Data::Transformer, Data::Visitor, Data::Walk.
TODO
Some kind of option making it possible to traverse objects with
Class::MOP metaclasses, so we can avoid breaking encapsulation.
Options to provide more information about the current node to the
callback handler, such as path, depth and data types. Should not affect
performance if not used.
LICENSE AND COPYRIGHT
Copyright 2010 Michael Zedeler.
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.