|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # This file is part of Config-Model  | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # This software is Copyright (c) 2005-2022 by Dominique Dumont.  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # This is free software, licensed under:  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #   The GNU Lesser General Public License, Version 2.1, February 1999  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use Carp;  | 
| 
12
 | 
59
 | 
 
 | 
 
 | 
  
59
  
 | 
 
 | 
366
 | 
 use strict;  | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
118
 | 
    | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3448
 | 
    | 
| 
13
 | 
59
 | 
 
 | 
 
 | 
  
59
  
 | 
 
 | 
314
 | 
 use warnings;  | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
109
 | 
    | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1050
 | 
    | 
| 
14
 | 
59
 | 
 
 | 
 
 | 
  
59
  
 | 
 
 | 
240
 | 
    | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
101
 | 
    | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1409
 | 
    | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use Config::Model::Exception;  | 
| 
16
 | 
59
 | 
 
 | 
 
 | 
  
59
  
 | 
 
 | 
268
 | 
 use Config::Model::ObjTreeScanner;  | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1718
 | 
    | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1230
 | 
    | 
| 
17
 | 
59
 | 
 
 | 
 
 | 
  
59
  
 | 
 
 | 
23514
 | 
 use Config::Model::Value;  | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
156
 | 
    | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1921
 | 
    | 
| 
18
 | 
59
 | 
 
 | 
 
 | 
  
59
  
 | 
 
 | 
37412
 | 
    | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
245
 | 
    | 
| 
 
 | 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
87778
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     bless {}, shift;  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
21
 | 
154
 | 
 
 | 
 
 | 
  
154
  
 | 
  
1
  
 | 
457
 | 
    | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     _quote( qr/[\s~"#*]/, @_ );  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
25
 | 
3772
 | 
 
 | 
 
 | 
  
3772
  
 | 
  
0
  
 | 
12868
 | 
     _quote( qr/[\s~"@*<>.=#]/, @_ );  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my ( $re, @res ) = @_;  | 
| 
29
 | 
4375
 | 
 
 | 
 
 | 
  
4375
  
 | 
  
0
  
 | 
11495
 | 
     foreach (@res) {  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if ( defined $_ and ( /$re/ or $_ eq '' ) ) {  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             s/"/\\"/g;    # escape present quotes  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $_ = '"' . $_ . '"';    # add my quotes  | 
| 
33
 | 
8147
 | 
 
 | 
 
 | 
  
8147
  
 | 
 
 | 
13338
 | 
         }  | 
| 
34
 | 
8147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12314
 | 
     }  | 
| 
35
 | 
8165
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
23597
 | 
     return wantarray ? @res : $res[0];  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
36
 | 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
571
 | 
 }  | 
| 
37
 | 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
599
 | 
    | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my @res = @_;  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     foreach (@res) {  | 
| 
40
 | 
8147
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
16703
 | 
         if ( defined $_ and $_ and (/(\s|"|\*)/) ) {  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             s/"/\\"/g;              # escape present quotes  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $_ = '"' . $_ . '"';    # add my quotes  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
44
 | 
5103
 | 
 
 | 
 
 | 
  
5103
  
 | 
  
0
  
 | 
8462
 | 
     }  | 
| 
45
 | 
5103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7462
 | 
     return wantarray ? @res : $res[0];  | 
| 
46
 | 
5103
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
15864
 | 
 }  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
47
 | 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
446
 | 
    | 
| 
48
 | 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
502
 | 
     my $self = shift;  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my %args    = @_;  | 
| 
51
 | 
5103
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10993
 | 
     my $full    = delete $args{full_dump} || 0;  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $skip_aw = delete $args{skip_auto_write} || '';  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $auto_v  = delete $args{auto_vivify} || 0;  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $mode    = delete $args{mode} || '';  | 
| 
55
 | 
154
 | 
 
 | 
 
 | 
  
154
  
 | 
  
1
  
 | 
261
 | 
    | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ($full) {  | 
| 
57
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
440
 | 
         carp "dump_tree: full_dump parameter is deprecated, please use mode => 'user'";  | 
| 
58
 | 
154
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
586
 | 
     }  | 
| 
59
 | 
154
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
525
 | 
    | 
| 
60
 | 
154
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
489
 | 
     my $check = delete $args{check} || 'yes';  | 
| 
61
 | 
154
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
515
 | 
     if ( $check !~ /yes|no|skip/ ) {  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         croak "dump_tree: unexpected 'check' value: $check";  | 
| 
63
 | 
154
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
366
 | 
     }  | 
| 
64
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # mode parameter is slightly different from fetch's mode  | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $fetch_mode =  | 
| 
67
 | 
154
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
470
 | 
           $full           ? 'user'  | 
| 
68
 | 
154
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1096
 | 
         : $mode eq 'full' ? 'user'  | 
| 
69
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         : $mode           ? $mode  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         :                   'custom';  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ( my $err = Config::Model::Value->is_bad_mode($fetch_mode) ) {  | 
| 
73
 | 
154
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
740
 | 
         croak "dump_tree: $err";  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $node = delete $args{node}  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         || croak "dump_tree: missing 'node' parameter";  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
79
 | 
154
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
2312
 | 
     my $compute_pad = sub {  | 
| 
80
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $depth = 0;  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $obj   = shift;  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         while ( defined $obj->parent ) {  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $depth++;  | 
| 
84
 | 
154
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
457
 | 
             $obj = $obj->parent;  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return '  ' x $depth;  | 
| 
87
 | 
4885
 | 
 
 | 
 
 | 
  
4885
  
 | 
 
 | 
6275
 | 
     };  | 
| 
88
 | 
4885
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6078
 | 
    | 
| 
89
 | 
4885
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12733
 | 
     my $leaf_cb = sub {  | 
| 
90
 | 
5979
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6571
 | 
         my ( $scanner, $data_r, $node, $element, $index, $value_obj ) = @_;  | 
| 
91
 | 
5979
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13333
 | 
    | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # get value or only customized value  | 
| 
93
 | 
4885
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10422
 | 
         my $value = quote( $value_obj->fetch( mode => $fetch_mode, check => $check ) );  | 
| 
94
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
727
 | 
         $index = id_quote($index);  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $pad = $compute_pad->($node);  | 
| 
97
 | 
3737
 | 
 
 | 
 
 | 
  
3737
  
 | 
 
 | 
6473
 | 
    | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $name =  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             defined $index  | 
| 
100
 | 
3737
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9514
 | 
             ? "$element:$index"  | 
| 
101
 | 
3734
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8749
 | 
             : $element;  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
103
 | 
3734
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8531
 | 
         # add annotation for obj contained in hash or list  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $note = note_quote( $value_obj->annotation );  | 
| 
105
 | 
3734
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
6968
 | 
         $$data_r .= "\n" . $pad . $name if defined $value or $note;  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if (defined $value) {  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $value =~ s/\\n/\\\\n/g;  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $$data_r .= '=' . $value;  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $$data_r .= '#' . $note         if $note;  | 
| 
111
 | 
3734
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8829
 | 
     };  | 
| 
112
 | 
3734
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
10795
 | 
    | 
| 
113
 | 
3734
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
6648
 | 
     my $check_list_cb = sub {  | 
| 
114
 | 
1242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2522
 | 
         my ( $scanner, $data_r, $node, $element, $index, $value_obj ) = @_;  | 
| 
115
 | 
1242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2091
 | 
    | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # get value or only customized value  | 
| 
117
 | 
3734
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
15929
 | 
         my $value = $value_obj->fetch( mode => $fetch_mode, check => $check );  | 
| 
118
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
672
 | 
         my $qvalue = quote($value);  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $index = id_quote($index);  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $pad = $compute_pad->($node);  | 
| 
121
 | 
38
 | 
 
 | 
 
 | 
  
38
  
 | 
 
 | 
93
 | 
    | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $name =  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             defined $index  | 
| 
124
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
154
 | 
             ? "$element:$index"  | 
| 
125
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
120
 | 
             : $element;  | 
| 
126
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
120
 | 
    | 
| 
127
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
102
 | 
         # add annotation for obj contained in hash or list  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $note = note_quote( $value_obj->annotation );  | 
| 
129
 | 
38
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
96
 | 
         $$data_r .= "\n" . $pad . $name if $value or $note;  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $$data_r .= '=' . $qvalue       if $value;  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $$data_r .= '#' . $note         if $note;  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $list_element_cb = sub {  | 
| 
135
 | 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
141
 | 
         my ( $scanner, $data_r, $node, $element, @keys ) = @_;  | 
| 
136
 | 
38
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
179
 | 
    | 
| 
137
 | 
38
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
108
 | 
         my $pad      = $compute_pad->($node);  | 
| 
138
 | 
38
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
522
 | 
         my $list_obj = $node->fetch_element($element);  | 
| 
139
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
586
 | 
    | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # add annotation for list element  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $list_note = note_quote( $list_obj->annotation );  | 
| 
142
 | 
312
 | 
 
 | 
 
 | 
  
312
  
 | 
 
 | 
715
 | 
         $$data_r .= "\n$pad$element#$list_note" if $list_note;  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
144
 | 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
682
 | 
         if ( $list_obj->cargo_type eq 'node' ) {  | 
| 
145
 | 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
808
 | 
             foreach my $k (@keys) {  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $scanner->scan_list( $data_r, $node, $element, $k );  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
148
 | 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
920
 | 
         }  | 
| 
149
 | 
312
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
633
 | 
         else {  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # write value comments  | 
| 
151
 | 
312
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
879
 | 
             foreach my $idx ( $list_obj->fetch_all_indexes ) {  | 
| 
152
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
                 my $note = $list_obj->fetch_with_id($idx)->annotation;  | 
| 
153
 | 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
113
 | 
                 $$data_r .= "\n$pad$element:$idx#" . note_quote($note) if $note;  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             # skip undef values  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             my @val = id_quote(  | 
| 
158
 | 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
793
 | 
                 grep { defined $_ }  | 
| 
159
 | 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
918
 | 
                     $list_obj->fetch_all_values(mode  => $fetch_mode, check => $check)  | 
| 
160
 | 
383
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1085
 | 
                 );  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $$data_r .= "\n$pad$element:=" . join( ',', @val ) if @val;  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
165
 | 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
878
 | 
     my $hash_element_cb = sub {  | 
| 
 
 | 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
590
 | 
    | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my ( $scanner, $data_r, $node, $element, @keys ) = @_;  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
168
 | 
295
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
2179
 | 
         my $pad      = $compute_pad->($node);  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $hash_obj = $node->fetch_element($element);  | 
| 
170
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
737
 | 
    | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # add annotation for list or hash element  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $note = note_quote( $hash_obj->annotation );  | 
| 
173
 | 
168
 | 
 
 | 
 
 | 
  
168
  
 | 
 
 | 
549
 | 
         $$data_r .= "\n$pad$element#$note" if $note;  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
175
 | 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
372
 | 
         # resume exploration  | 
| 
176
 | 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
470
 | 
         map { $scanner->scan_hash( $data_r, $node, $element, $_ ); } @keys;  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
179
 | 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
487
 | 
     # called for nodes contained in nodes (not root).  | 
| 
180
 | 
168
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
408
 | 
     # This node can be held by a plain element or a hash element or a list element  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $node_element_cb = sub {  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my ( $scanner, $data_r, $node, $element, $key, $contained_node ) = @_;  | 
| 
183
 | 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
395
 | 
    | 
| 
 
 | 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1116
 | 
    | 
| 
184
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
561
 | 
         my $type = $node->element_type($element);  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         return if $skip_aw and $contained_node->is_auto_write_for_type($skip_aw);  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $pad = $compute_pad->($node);  | 
| 
189
 | 
633
 | 
 
 | 
 
 | 
  
633
  
 | 
 
 | 
1399
 | 
         my $elt = $node->fetch_element($element);  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
191
 | 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1631
 | 
         # load string can feature only one comment per element_type  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # ie foo#comment foo:bar#comment foo:bar=val#comment are fine  | 
| 
193
 | 
633
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
1585
 | 
         # but foo#comment:bar if not valid -> foo#commaent foo:bar  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
195
 | 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1417
 | 
         my $head      = "\n$pad$element";  | 
| 
196
 | 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1538
 | 
         my $node_note = note_quote( $contained_node->annotation );  | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         if ( $type eq 'list' or $type eq 'hash' ) {  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $head .= ':' . id_quote($key);  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $head .= '#' . $node_note if $node_note;  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             my $sub_data = '';  | 
| 
202
 | 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1821
 | 
             $scanner->scan_node( \$sub_data, $contained_node );  | 
| 
203
 | 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1785
 | 
             $$data_r .= $head . $sub_data . ' -';  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
205
 | 
633
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
2293
 | 
         else {  | 
| 
206
 | 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
888
 | 
             $head .= '#' . $node_note if $node_note;  | 
| 
207
 | 
308
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
905
 | 
             my $sub_data = '';  | 
| 
208
 | 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
577
 | 
             $scanner->scan_node( \$sub_data, $contained_node );  | 
| 
209
 | 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1275
 | 
    | 
| 
210
 | 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2994
 | 
             # skip simple nodes that do not bring data  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             $$data_r .= $head . $sub_data . ' -' if $sub_data;  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
213
 | 
325
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
722
 | 
     };  | 
| 
214
 | 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
520
 | 
    | 
| 
215
 | 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1302
 | 
     my @scan_args = (  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         fallback => 'all',  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         auto_vivify           => $auto_v,  | 
| 
218
 | 
325
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
2477
 | 
         list_element_cb       => $list_element_cb,  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         hash_element_cb       => $hash_element_cb,  | 
| 
220
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
648
 | 
         leaf_cb               => $leaf_cb,  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         node_element_cb       => $node_element_cb,  | 
| 
222
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
659
 | 
         check_list_element_cb => $check_list_cb,  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         check                 => $check,  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my @left = keys %args;  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     croak "Dumper: unknown parameter:@left" if @left;  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # perform the scan  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $view_scanner = Config::Model::ObjTreeScanner->new(@scan_args);  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $ret       = '';  | 
| 
233
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
303
 | 
     my $root_note = note_quote( $node->annotation );  | 
| 
234
 | 
154
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
397
 | 
     $ret .= "\n#$root_note" if $root_note;  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $view_scanner->scan_node( \$ret, $node );  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
237
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1057
 | 
     substr( $ret, 0, 1, '' );    # remove leading \n  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $ret .= ' -' if $ret;  | 
| 
239
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
322
 | 
     return $ret . "\n";  | 
| 
240
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
741
 | 
 }  | 
| 
241
 | 
154
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
362
 | 
    | 
| 
242
 | 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
660
 | 
 1;  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
244
 | 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
736
 | 
 # ABSTRACT: Serialize data of config tree  | 
| 
245
 | 
151
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
452
 | 
    | 
| 
246
 | 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7381
 | 
    | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =pod  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =encoding UTF-8  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Config::Model::Dumper - Serialize data of config tree  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 VERSION  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 version 2.151  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  use Config::Model ;  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # define configuration tree object  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $model = Config::Model->new ;  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $model ->create_config_class (  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     name => "MyClass",  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     element => [  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         [qw/foo bar/] => {  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             type => 'leaf',  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             value_type => 'string'  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         },  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         baz => {  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             type => 'hash',  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             index_type => 'string' ,  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             cargo => {  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 type => 'leaf',  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 value_type => 'string',  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             },  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         },  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ],  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  ) ;  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $inst = $model->instance(root_class_name => 'MyClass' );  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $root = $inst->config_root ;  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # put some data in config tree the hard way  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $root->fetch_element('foo')->store('yada') ;  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $root->fetch_element('bar')->store('bla bla') ;  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $root->fetch_element('baz')->fetch_with_id('en')->store('hello') ;  | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # put more data the easy way  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $steps = 'baz:fr=bonjour baz:hr="dobar dan"';  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $root->load( steps => $steps ) ;  | 
| 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  # dump only customized data  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  print $root->dump_tree;  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This module is used directly by L<Config::Model::Node> to serialize  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 configuration data in a compact (but readable) string.  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The serialization can be done in standard mode where only customized  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 values are dumped in the string. I.e. only data modified by the user  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 are dumped.  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 All other mode supported by L<Config::Model::Value/fetch> can be used,  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 for instance, to get default values.  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The serialized string can be used by L<Config::Model::Loader> to store  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the data back into a configuration tree.  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Note that undefined values are skipped for list element. I.e. if a list  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 element contains C<('a',undef,'b')>, the dump then contains C<'a','b'>.  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 CONSTRUCTOR  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 new  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 No parameter. The constructor should be used only by  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L<Config::Model::Node>.  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 Methods  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 dump_tree  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Return a string that contains a dump of the object tree with all the  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 values. This string follows the convention defined by  | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L<Config::Model::Loader>.  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The serialized string can be used by L<Config::Model::Loader> to store  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the data back into a configuration tree.  | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Parameters are:  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item mode  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C<full> dumps all configuration data including default  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 values.  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 All mode values from L<Config::Model::Value/fetch> can be used.  | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 By default, the dump contains only data modified by the user  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 (i.e. C<custom> data that differ from default or preset values).  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item node  | 
| 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Reference to the L<Config::Model::Node> object that is dumped. All  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 nodes and leaves attached to this node are also dumped.  | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item skip_auto_write ( <backend_name> )  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Skip node that have a write capability matching C<backend_name> in  | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 their model. See L<Config::Model::BackendMgr>.  | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This option must be used when using Dumper to write back configuration  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 data. When a configuration model contains several backends (one at the  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 tree root and others in tree nodes), setting this option ensure that  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the "root" configuration file does not contain data duplicated in  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 configuration file of others tree nodes.  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item auto_vivify  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Scan and create data for nodes elements even if no actual data was  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 stored in them. This may be useful to trap missing mandatory values.  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 (default: 0)  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item check  | 
| 
373
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Check value before dumping. Valid check are 'yes', 'no' and 'skip'.  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Dominique Dumont, (ddumont at cpan dot org)  | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SEE ALSO  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L<Config::Model>,L<Config::Model::Node>,L<Config::Model::Loader>  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Dominique Dumont  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT AND LICENSE  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This software is Copyright (c) 2005-2022 by Dominique Dumont.  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is free software, licensed under:  | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   The GNU Lesser General Public License, Version 2.1, February 1999  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  |