1Config::Model::ObjTreeSUcsaenrneCro(n3tprmi)buted Perl DCoocnufmiegn:t:aMtoidoenl::ObjTreeScanner(3pm)
2
3
4

NAME

6       Config::Model::ObjTreeScanner - Scan config tree and perform call-backs
7       for each element or node
8

VERSION

10       version 2.153
11

SYNOPSIS

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

DESCRIPTION

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

CONSTRUCTOR

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

Callback prototypes

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

METHODS

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

AUTHOR

356       Dominique Dumont, (ddumont at cpan dot org)
357

SEE ALSO

359       Config::Model,Config::Model::Node,Config::Model::Instance,
360       Config::Model::HashId, Config::Model::ListId, Config::Model::CheckList,
361       Config::Model::Value
362

AUTHOR

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.38.0                      2023-07-25Config::Model::ObjTreeScanner(3pm)
Impressum