File Coverage

lib/Config/Proxy/Node.pm
Criterion Covered Total %
statement 78 92 84.7
branch 21 38 55.2
condition 3 5 60.0
subroutine 19 21 90.4
pod 14 15 93.3
total 135 171 78.9


line stmt bran cond sub pod time code
1             package Config::Proxy::Node;
2 7     7   3412 use strict;
  7         13  
  7         258  
3 7     7   34 use warnings;
  7         10  
  7         367  
4 7     7   75 use Carp;
  7         58  
  7         510  
5 7     7   3146 use Config::Proxy::Iterator;
  7         20  
  7         942  
6              
7             sub new {
8 162     162 0 1892 my $class = shift;
9 162         650 local %_ = @_;
10             bless {
11             _kw => $_{kw},
12             _argv => $_{argv} // [],
13             _orig => $_{orig},
14             _locus => $_{locus},
15             _parent => $_{parent},
16 162   100     1722 _index => -1
17             }, $class;
18             }
19              
20             my @ATTRIBUTES = qw(kw orig locus parent index);
21              
22             {
23 7     7   48 no strict 'refs';
  7         12  
  7         8939  
24             foreach my $attribute (@ATTRIBUTES) {
25             *{ __PACKAGE__ . '::' . $attribute } = sub {
26 1396     1396   1786 my $self = shift;
27 1396 100       2442 if (defined(my $val = shift)) {
28 286 50       462 croak "too many arguments" if @_;
29 286         565 $self->{'_'.$attribute} = $val;
30             }
31 1396         3874 return $self->{'_'.$attribute};
32             }
33             }
34             }
35              
36             sub argv {
37 0     0 1 0 my $self = shift;
38 0 0       0 if (my $val = shift) {
39 0 0       0 croak "too many arguments" if @_;
40 0         0 $self->{_argv} = $val;
41 0         0 delete $self->{_orig};
42             }
43 0         0 return @{$self->{_argv}};
  0         0  
44             }
45              
46             sub arg {
47 36     36 1 81 my $self = shift;
48 36         47 my $n = shift;
49 36 50       71 if (my $val = shift) {
50 0 0       0 croak "too many arguments" if @_;
51 0         0 $self->{_argv}[$n] = $val;
52             }
53 36         128 return $self->{_argv}[$n];
54             }
55              
56             sub drop {
57 5     5 1 8 my $self = shift;
58 5         11 $self->parent->delete_node($self->index);
59             }
60              
61             sub iterator {
62 80     80 1 285 return new Config::Proxy::Iterator(@_);
63             }
64              
65             sub write {
66 4     4 1 7 my $self = shift;
67 4         6 my $file = shift;
68 4         5 my $fh;
69              
70 4 50       13 if (!defined($file)) {
71 0         0 $file = \*STDOUT
72             }
73 4 50       15 if (ref($file) eq 'GLOB') {
74 0         0 $fh = $file;
75             } else {
76 4 50       66 open($fh, '>', $file) or croak "can't open $file: $!";
77             }
78              
79 4 50 33     22 $self->format($fh, @_) if $self->is_section && !$self->is_root;
80              
81 4         13 my $itr = $self->iterator(inorder => 1);
82              
83 4         13 while (defined(my $node = $itr->next)) {
84 52         112 $node->format($fh, @_);
85             }
86              
87 4 50       41 close $fh unless ref($file) eq 'GLOB';
88             }
89              
90             sub format {
91 52     52 1 128 my ($self, $fh, %opts) = @_;
92              
93 52         141 my $s = $self->as_string;
94 52 100       123 if ($opts{indent}) {
95 39 100       91 if ($self->is_comment) {
96 3 100       9 if ($opts{reindent_comments}) {
97 1         14 my $indent = ' ' x ($opts{indent} * $self->depth);
98 1         5 $s =~ s/^\s+//;
99 1         3 $s = $indent . $s;
100             }
101             } else {
102 36         74 my $indent = ' ' x ($opts{indent} * $self->depth);
103 36 100       61 if ($opts{tabstop}) {
104 12         37 $s = $indent . $self->kw;
105 12         43 for (my $i = 0; my $arg = $self->arg($i); $i++) {
106 13         15 my $off = 1;
107 13 50       16 if ($i < @{$opts{tabstop}}) {
  13         73  
108 13 100       33 if (($off = $opts{tabstop}[$i] - length($s)) <= 0) {
109 1         2 $off = 1;
110             }
111             }
112 13         43 $s .= (' ' x $off) . $arg;
113             }
114             } else {
115 24         97 $s =~ s/^\s+//;
116 24         48 $s = $indent . $s;
117             }
118             }
119             }
120 52         212 print $fh $s,"\n";
121             }
122              
123             sub depth {
124 109     109 1 146 my $self = shift;
125 109         132 my $n = 0;
126 109         226 while ($self = $self->parent) {
127 309         539 $n++;
128             }
129 109         265 return $n - 1;
130             }
131              
132             sub root {
133 5     5 1 10 my $self = shift;
134 5         8 while ($self->parent()) {
135 10         19 $self = $self->parent();
136             }
137 5         14 return $self;
138             }
139              
140             sub as_string {
141 236     236 1 341 my $self = shift;
142 236 50       411 if (defined(my $v = $self->orig)) {
143 236         606 return $v;
144             }
145 0 0       0 return '' unless $self->kw;
146 0         0 return $self->orig(join(' ', ($self->kw, $self->argv())));
147             }
148              
149             # use overload
150             # '""' => sub { shift->as_string };
151              
152 13     13 1 48 sub is_root { 0 }
153 341     341 1 1016 sub is_section { 0 }
154 28     28 1 145 sub is_statement { 0 }
155 0     0 1 0 sub is_empty { 0 }
156 102     102 1 204 sub is_comment { 0 }
157              
158             1;
159             __END__