NAME
Config::Model::ObjTreeScanner - Scan config tree and perform call-backs
SYNOPSIS
use Config::Model::ObjTreeScanner ;
# define configuration tree object
my $root = ... ;
# define leaf call back
my disp_leaf = sub {
my ($scanner, $data_ref, $node,$element_name,$index, $leaf_object) = @_ ;
$$data_ref .= "$element_name = ", $leaf_object->fetch ;
} ;
# simple scanner, (print all values with 'intermediate' permission
$scan = Config::Model::ObjTreeScanner-> new
(
leaf_cb => \&disp_leaf, # only mandatory parameter
) ;
my $result = '';
$scan->scan_node(\$result, $root) ;
# For a more complex scanner
$scan = Config::Model::ObjTreeScanner-> new
(
fallback => 'none', # all callback must be defined
permission => 'master', # consider all values
# node callback
list_cb => \&disp_hash ,
check_list_cb => \&disp_hash ,
hash_cb => \&disp_hash ,
element_cb => \&disp_obj ,
node_cb => \&disp_obj_elt ,
# leaf callback
leaf_cb => \&disp_leaf,
enum_value_cb => \&disp_leaf,
enum_integer_value_cb => \&disp_leaf,
integer_value_cb => \&disp_leaf,
number_value_cb => \&disp_leaf,
boolean_value_cb => \&disp_leaf,
string_value_cb => \&disp_leaf,
reference_value_cb => \&disp_leaf,
) ;
$scan->scan_node(\$result, $root) ;
DESCRIPTION
This module creates an object that will explore (depth first) a configuration tree.
For each node or leaf encountered, the ObjTreeScanner object will call-back one of the subroutine reference passed during construction.
To continue the exploration, these call-backs must also call the scanner. (i.e. perform another call-back). In other words the user's subroutine and the scanner plays a game of ping-pong until the tree is completely explored.
The scanner provides a set of default callback for the nodes. This way, the user only have to provide call-backs for the leaves.
The scan is started with a call to scan_node
. The first parameter of scan_node is a ref that is passed untouched to all call-back. This ref may be used to store whatever result you want.
CONSTRUCTOR
new ( ... )
One way or another, the ObjTreeScanner object must be able to find all callback for all the items of the tree. All the possible call-back are listed below:
- leaf callback:
-
leaf_cb
,enum_value_cb
,enum_integer_value_cb
,integer_value_cb
,number_value_cb
,boolean_value_cb
,string_value_cb
,reference_value_cb
- node callback:
-
list_cb
,check_list_cb
,hash_cb
,element_cb
,node_cb
.
The user may specify all of them by passing the sub ref to the constructor:
$scan = Config::Model::ObjTreeScanner-> new
(
# node callback
list_cb => sub ,
...
)
Or use some default callback using the fallback parameter. Note that at least one callback must be provided: leaf_cb
.
Optional parameter:
- fallback
-
If set to 'node', the scanner will provide default call-back for node items. If set to 'leaf', the scanner will set all leaf callback (like enum_integer_value_cb, enum_value_cb ...) to string_value_cb or to the mandatory leaf_cb value. "fallback" callback will not override callbacks provided by the user.
If set to 'all', equivalent to 'node' and 'leaf'.
- permission
-
Set the privilege level used for the scan (default 'intermediate').
- auto_vivify
-
Whether to create the configuration items while scan (default is 1).
Callback prototypes
The leaf callback will be called with the following parameters:
($scanner, $data_ref,$node,$element_name,$index, $leaf_object)
where:
$scanner
is the scanner object.$data_ref
is the reference passwd to the first call of the scanner.$node
is the node that contain the leaf.$element_name
is the element (or attribute) that contain the leaf.$index
is the index (or hash key) used to get the leaf. This may be undefined if the element type is scalar.$leaf_object
is a Config::Model::Value object.
Others :
list_cb
:-
($scanner, $data_ref,$node,$element_name,@indexes)
@indexes
is an list containing all the indexes of the array.Example:
sub my_list_cb { my ($scanner, $data_ref,$node,$element_name,@idx) = @_ ; # custom code using $data_ref # resume exploration (if needed) map {$scanner->scan_list($data_ref,$node,$element_name,$_)} @idx ; }
check_list_cb
:-
($scanner, $data_ref,$node,$element_name,@indexes)
@indexes
is an list containing all the indexes of the array. hash_cb
:-
($scanner, $data_ref,$node,$element_name,@keys)
@keys
is an list containing all the keys of the hash.Example:
sub my_hash_cb { my ($scanner, $data_ref,$node,$element_name,@keys) = @_ ; # custom code using $data_ref # resume exploration map {$scanner->scan_hash($data_ref,$node,$element_name,$_)} @keys ; }
element_cb
:-
($scanner, $data_ref,$node,@element_list)
@element_list
contains all the elements of the node.Example:
sub my_element_cb = { my ($scanner, $data_ref,$node,@element) = @_ ; # custom code using $data_ref # resume exploration map {$scanner->scan_element($data_ref, $node,$_)} @element ; }
node_cb
-
($scanner, $data_ref,$node,$element_name,$key, $next_node)
$key
may be undef if$node
's element not a hash or a list.$element_name
and$key
specifies the element name and key of the the node you want to scan. (passed with$next_node
) Note that$next_node
may be undef ifauto_vivify
is 0.Example:
sub my_node_cb { my ($scanner, $data_ref,$node,$element_name,$key, $next_node) = @_ # your custom code using $data_ref # explore next node $scanner->scan_node($data_ref,$next_node); }
METHODS
scan_node ($data_r,$node)
Explore the node and call element_cb
passing all element names.
scan_element($data_r,$node,$element_name)
Explore the element and call either hash_cb
, list_cb
, node_cb
or a leaf call-back (the leaf call-back called depends on the Value object properties: enum, string, integer and so on)
scan_hash ($data_r,$node,$element_name,$key)
Explore the hash member (or hash value) and call either node_cb
or a leaf call-back.
scan_list ($data_r,$node,$element_name,$index)
Just like scan_hash
: Explore the list member and call either node_cb
or a leaf call-back.
get_keys ($node, $element_name)
Returns an list containing the sorted keys of a hash element or returns an list containning (0.. last_index) of an list element.
Throws an exception if element is not an list or a hash element.