1Config::Model::ObjTreeSUcsaenrneCro(n3t)ributed Perl DocCuomnefnitga:t:iMoondel::ObjTreeScanner(3)
2
3
4
6 Config::Model::ObjTreeScanner - Scan config tree and perform call-backs
7 for each element or node
8
10 version 2.152
11
13 use Config::Model ;
14
15 # define configuration tree object
16 my $model = Config::Model->new ;
17 $model ->create_config_class (
18 name => "MyClass",
19 element => [
20 [qw/foo bar/] => {
21 type => 'leaf',
22 value_type => 'string'
23 },
24 baz => {
25 type => 'hash',
26 index_type => 'string' ,
27 cargo => {
28 type => 'leaf',
29 value_type => 'string',
30 },
31 },
32
33 ],
34 ) ;
35
36 my $inst = $model->instance(root_class_name => 'MyClass' );
37
38 my $root = $inst->config_root ;
39
40 # put some data in config tree the hard way
41 $root->fetch_element('foo')->store('yada') ;
42 $root->fetch_element('bar')->store('bla bla') ;
43 $root->fetch_element('baz')->fetch_with_id('en')->store('hello') ;
44
45 # put more data the easy way
46 my $steps = 'baz:fr=bonjour baz:hr="dobar dan"';
47 $root->load( steps => $steps ) ;
48
49 # define leaf call back
50 my $disp_leaf = sub {
51 my ($scanner, $data_ref, $node,$element_name,$index, $leaf_object) = @_ ;
52 $$data_ref .= "disp_leaf called for '". $leaf_object->name.
53 "' value '".$leaf_object->fetch."'\n";
54 } ;
55
56 # simple scanner, (print all values)
57 my $scan = Config::Model::ObjTreeScanner-> new (
58 leaf_cb => $disp_leaf, # only mandatory parameter
59 ) ;
60
61 my $result = '';
62 $scan->scan_node(\$result, $root) ;
63 print $result ;
64
66 This module creates an object that explores (depth first) a
67 configuration tree.
68
69 For each part of the configuration tree, ObjTreeScanner object calls
70 one of the subroutine reference passed during construction. (a call-
71 back or a hook)
72
73 Call-back and hook routines are called:
74
75 • For each node containing elements (including root node)
76
77 • For each element of a node. This element can be a list, hash, node
78 or leaf element.
79
80 • For each item contained in a node, hash or list. This item can be a
81 leaf or another node.
82
83 To continue the exploration, these call-backs must also call the
84 scanner. (i.e. perform another call-back). In other words the user's
85 subroutine and the scanner play a game of ping-pong until the tree is
86 completely explored.
87
88 Hooks routines are not required to resume the exploration, i.e. to call
89 the scanner. This is done once the hook routine has returned.
90
91 The scanner provides a set of default callback for the nodes. This way,
92 the user only have to provide call-backs for the leaves.
93
94 The scan is started with a call to "scan_node". The first parameter of
95 scan_node is a ref that is passed untouched to all call-back. This ref
96 may be used to store whatever result you want.
97
99 new
100 One way or another, the ObjTreeScanner object must be able to find all
101 callback for all the items of the tree. All the possible call-back and
102 hooks are listed below:
103
104 leaf callback:
105 "leaf_cb" is a catch-all generic callback. All other are
106 specialized call-back : "enum_value_cb", "integer_value_cb",
107 "number_value_cb", "boolean_value_cb", "string_value_cb",
108 "uniline_value_cb", "reference_value_cb"
109
110 node callback:
111 "node_content_cb" , "node_dispatch_cb"
112
113 node hooks:
114 "node_content_hook"
115
116 element callback:
117 All these call-backs are called on the elements of a node:
118 "list_element_cb", "check_list_element_cb", "hash_element_cb",
119 "node_element_cb", "node_content_cb".
120
121 element hooks:
122 "list_element_hook", "hash_element_hook".
123
124 The user may specify all of them by passing a sub ref to the
125 constructor:
126
127 $scan = Config::Model::ObjTreeScanner-> new
128 (
129 list_element_cb => sub { ... },
130 ...
131 )
132
133 Or use some default callback using the fallback parameter. Note that at
134 least one callback must be provided: "leaf_cb".
135
136 Optional parameter:
137
138 fallback
139 If set to "node", the scanner provides default call-back for node
140 items. If set to "leaf", the scanner sets all leaf callback (like
141 enum_value_cb ...) to string_value_cb or to the mandatory leaf_cb
142 value. "fallback" callback does not override callbacks provided by
143 the user.
144
145 If set to "all" , the scanner provides fallbacks for leaf and node.
146 By default, all fallback are provided.
147
148 auto_vivify
149 Whether to create configuration objects while scanning (default is
150 1).
151
152 check
153 "yes", "no" or "skip".
154
156 Leaf callback
157 "leaf_cb" is called for each leaf of the tree. The leaf callback is
158 called with the following parameters:
159
160 ($scanner, $data_ref,$node,$element_name,$index, $leaf_object)
161
162 where:
163
164 • $scanner is the scanner object.
165
166 • $data_ref is a reference that is first passed to the first call of
167 the scanner. Then $data_ref is relayed through the various call-
168 backs
169
170 • $node is the node that contain the leaf.
171
172 • $element_name is the element (or attribute) that contain the leaf.
173
174 • $index is the index (or hash key) used to get the leaf. This may be
175 undefined if the element type is scalar.
176
177 • $leaf_object is a Config::Model::Value object.
178
179 List element callback
180 "list_element_cb" is called on all list element of a node, i.e. call on
181 the list object itself and not in the elements contained in the list.
182
183 ($scanner, $data_ref,$node,$element_name,@indexes)
184
185 @indexes is a list containing all the indexes of the list.
186
187 Example:
188
189 sub my_list_element_cb {
190 my ($scanner, $data_ref,$node,$element_name,@idx) = @_ ;
191
192 # custom code using $data_ref
193
194 # resume exploration (if needed)
195 map {$scanner->scan_list($data_ref,$node,$element_name,$_)} @idx ;
196
197 # note: scan_list and scan_hash are equivalent
198 }
199
200 List element hook
201 "list_element_hook": Works like the list element callback. Except that
202 the calls to "scan_list" are not required. This is done once the hook
203 returns.
204
205 Check list element callback
206 "check_list_element_cb": Like "list_element_cb", but called on a
207 check_list element.
208
209 ($scanner, $data_ref,$node,$element_name, index, check_list_obj)
210
211 "index" is always undef as a check_list cannot be contained in a hash
212 or list (yet)
213
214 Hash element callback
215 "hash_element_cb": Like "list_element_cb", but called on a hash
216 element.
217
218 ($scanner, $data_ref,$node,$element_name,@keys)
219
220 @keys is an list containing all the keys of the hash.
221
222 Example:
223
224 sub my_hash_element_cb {
225 my ($scanner, $data_ref,$node,$element_name,@keys) = @_ ;
226
227 # custom code using $data_ref
228
229 # resume exploration
230 map {$scanner->scan_hash($data_ref,$node,$element_name,$_)} @keys ;
231 }
232
233 Hash element hook
234 "hash_element_hook": Works like the hash element callback. Except that
235 the calls to "scan_hash" are not required. This is done once the hook
236 returns.
237
238 Node content callback
239 "node_content_cb": This call-back is called foreach node (including
240 root node).
241
242 ($scanner, $data_ref,$node,@element_list)
243
244 @element_list contains all the element names of the node.
245
246 Example:
247
248 sub my_content_cb {
249 my ($scanner, $data_ref,$node,@element) = @_ ;
250
251 # custom code using $data_ref
252
253 # resume exploration
254 map {$scanner->scan_element($data_ref, $node,$_)} @element ;
255 }
256
257 Node content hook
258 "node_content_hook": This hook is called foreach node (including root
259 node). Works like the node content call-back. Except that the calls to
260 "scan_element" are not required. This is done once the hook returns.
261
262 Dispatch node callback
263 "node_dispatch_cb": Any callback specified in the hash is called for
264 each instance of the specified configuration class. (this may include
265 the root node).
266
267 For instance, if you have:
268
269 node_dispach_cb => {
270 ClassA => \&my_class_a_dispatch_cb,
271 ClassB => \&my_class_b_dispatch_cb,
272 }
273
274 &my_class_a_dispatch_cb is called for each instance of "ClassA" and
275 &my_class_b_dispatch_cb is called for each instance of "ClassB".
276
277 They is called with the following parameters:
278
279 ($scanner, $data_ref,$node,@element_list)
280
281 @element_list contains all the element names of the node.
282
283 Example:
284
285 sub my_class_a_dispatch_cb = {
286 my ($scanner, $data_ref,$node,@element) = @_ ;
287
288 # custom code using $data_ref
289
290 # resume exploration
291 map {$scanner->scan_element($data_ref, $node,$_)} @element ;
292 }
293
294 Node element callback
295 "node_element_cb" is called for each node contained within a node (i.e
296 not with root node). This node can be held by a plain element or a hash
297 element or a list element:
298
299 ($scanner, $data_ref,$node,$element_name,$key, $contained_node)
300
301 $key may be undef if $contained_node is not a part of a hash or a list.
302 $element_name and $key specifies the element name and key of the the
303 contained node you want to scan. (passed with $contained_node) Note
304 that $contained_node may be undef if "auto_vivify" is 0.
305
306 Example:
307
308 sub my_node_element_cb {
309 my ($scanner, $data_ref,$node,$element_name,$key, $contained_node) = @_;
310
311 # your custom code using $data_ref
312
313 # explore next node
314 $scanner->scan_node($data_ref,$contained_node);
315 }
316
318 scan_node
319 Parameters: "($data_r,$node)"
320
321 Explore the node and call either "node_dispatch_cb" (if the node class
322 name matches the dispatch_node hash) or (e.g. xor) "node_element_cb"
323 passing all element names.
324
325 "up_cb" is called once the first callback returns.
326
327 scan_element
328 Parameters: "($data_r,$node,$element_name)"
329
330 Explore the element and call either "hash_element_cb",
331 "list_element_cb", "node_content_cb" or a leaf call-back (the leaf
332 call-back called depends on the Value object properties: enum, string,
333 integer and so on)
334
335 scan_hash
336 Parameters: "($data_r,$node,$element_name,$key)"
337
338 Explore the hash member (or hash value) and call either
339 "node_content_cb" or a leaf call-back.
340
341 scan_list
342 Parameters: "($data_r,$node,$element_name,$index)"
343
344 Just like "scan_hash": Explore the list member and call either
345 "node_content_cb" or a leaf call-back.
346
347 get_keys
348 Parameters: "($node, $element_name)"
349
350 Returns an list containing the sorted keys of a hash element or returns
351 an list containing (0.. last_index) of an list element.
352
353 Throws an exception if element is not an list or a hash element.
354
356 Dominique Dumont, (ddumont at cpan dot org)
357
359 Config::Model,Config::Model::Node,Config::Model::Instance,
360 Config::Model::HashId, Config::Model::ListId, Config::Model::CheckList,
361 Config::Model::Value
362
364 Dominique Dumont
365
367 This software is Copyright (c) 2005-2022 by Dominique Dumont.
368
369 This is free software, licensed under:
370
371 The GNU Lesser General Public License, Version 2.1, February 1999
372
373
374
375perl v5.36.0 2023-01-20 Config::Model::ObjTreeScanner(3)