File Coverage

blib/lib/Config/Nested/Section.pm
Criterion Covered Total %
statement 46 65 70.7
branch 11 14 78.5
condition 1 3 33.3
subroutine 10 11 90.9
pod 1 2 50.0
total 69 95 72.6


line stmt bran cond sub pod time code
1             #! /usr/bin/env perl
2              
3             =head1 NAME
4              
5             Config::Nested::Section - contain the configuration from a section statement in a Config::Nested configuration file.
6              
7             =head1 SYNOPSIS
8              
9             use Config::Nested;
10             use Data::Dumper;
11              
12             my $obj = new Config::Nested::Section(
13             list => [],
14             owner => '',
15             location=> '',
16             colour => {},
17             contents=> {},
18             );
19              
20             $obj->owner('Fred');
21             $obj->location('here');
22             $obj->list(qw(a b c d e));
23              
24             my $clone = $obj->new();
25              
26             print Dumper($obj);
27              
28             This produces the output:
29              
30             $VAR1 = bless( {
31             'colour' => {},
32             'contents' => {},
33             'list' => [ 'a', 'b', 'c', 'd', 'e' ],
34             'location' => 'here',
35             'owner' => 'Fred'
36             }, 'Config::Nested::Section' );
37              
38             =head1 DESCRIPTION
39              
40             Config::Nested::Section is a hash array containing the configuration for
41             a individual section parsed from a Config::Nested configuration file.
42              
43             =head1 EXPORTS
44              
45             Nothing.
46              
47             =head1 FUNCTIONS
48              
49             =cut
50              
51             # Config::Nested::Sect
52             #
53             # Anthony Fletcher 1st Jan 2007
54             #
55              
56             package Config::Nested::Section;
57              
58             $VERSION = '1.0';
59              
60 5     5   93524 use 5;
  5         28  
  5         255  
61 5     5   29 use warnings;
  5         9  
  5         169  
62 5     5   27 use strict;
  5         12  
  5         287  
63 5     5   40 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD);
  5         8  
  5         391  
64              
65             # Standard modules.
66 5     5   39 use Data::Dumper;
  5         9  
  5         338  
67 5     5   27 use Storable qw(dclone);
  5         7  
  5         226  
68 5     5   28 use Carp;
  5         10  
  5         396  
69              
70             use overload
71             #'=' => sub { die; },
72             #'=' => sub { print join(',', caller(0)), "\n"; die; 1; },
73             #'bool' => sub { print join(',', caller(0)), "\n"; die; 1; },
74             #'bool' => sub { return (defined($_[0]) ? 1 : 0); },
75 5     5   29 ;
  5         11  
  5         64  
76              
77              
78             my $PACKAGE = __PACKAGE__ ;
79              
80             # module configuration
81             $Data::Dumper::Sortkeys = 1;
82              
83             =pod
84              
85             =head2 $section = Bnew( options )>
86              
87             =head2 B<$section-Econfigure( options )>
88              
89             Construct a new Config::Nested::Section object;
90             options can be listed as I value> pairs.
91             The keys are
92              
93             =over 4
94              
95             =item *
96              
97             scalar =E Earray of variableE
98              
99             =item *
100              
101             array =E Earray of variableE
102              
103             =item *
104              
105             hash =E Earray of variableE
106              
107             =back
108              
109             If this constructor is applied to an existing Config::Nested::Section
110             object, then the object is cloned, augmented with the extra options and returned.
111              
112             =cut
113              
114             # Create a new object
115             sub new
116             {
117             # Create an object.
118 8     8 1 38 my $this = shift;
119              
120 8         15 my $self;
121 8 100       28 if (ref($this))
122             {
123             # $this is already an object!
124             # Clone it.
125 2         315 $self = dclone($this);
126             }
127             else
128             {
129 6   33     42 my $class = ref($this) || $this;
130 6         15 $self = { };
131 6         23 bless $self, $class;
132             }
133              
134 8 50       44 croak "Odd number of arguments" if @_ % 2;
135              
136 8         39 my %arg = @_;
137 8         32 for my $k (keys %arg)
138             {
139 15         178 $self->{$k} = $arg{$k};
140             }
141              
142             #warn Dumper(\$self);
143              
144 8         49 $self;
145             }
146              
147             =head2 B<$section-Emember(..)>
148              
149             Either lookup or set the member variable corresponding to the keys of
150             the hash array underlying the Config::Nested::Section object. If the
151             particular member key is not present in the underlying hash, an
152             error occurs.
153              
154             If the function is given arguments, then the value is set in the object,
155             before returning the new value. This allows the following:
156              
157             my $b = new Config::Nested::Section(array => 'path');
158             $b->path->[0] ='first step';
159              
160             The only member function that does not work this way is 'new', which is
161             the constructor function and returns a cloned copy.
162              
163             =cut
164              
165             # Autoload all of the member functions.
166             sub AUTOLOAD
167             {
168 21     21   4398 my $this = shift;
169              
170             # DESTROY messages should never be propagated.
171 21 50       67 return if $AUTOLOAD =~ /::DESTROY$/;
172              
173             # Isolate the function name.
174 21         218 $AUTOLOAD =~ s/^\Q$PACKAGE\E:://;
175              
176             # Is this a real function?
177 21 100       68 unless (exists $this->{$AUTOLOAD})
178             {
179 1         199 croak "member variable '$AUTOLOAD' does not exist";
180             }
181              
182             # Values to set?
183 20 100       50 if (@_)
184             {
185             # Set the value?
186 4 100       23 if (ref $this->{$AUTOLOAD} eq '')
    50          
187             {
188 3         29 $this->{$AUTOLOAD} = shift;
189             }
190             elsif (ref $this->{$AUTOLOAD} eq 'ARRAY')
191             {
192 1         5 $this->{$AUTOLOAD} = [ @_ ];
193             }
194             else
195             {
196 0         0 croak "case not handled for $AUTOLOAD";
197             }
198              
199             # Interesting but usuab;e from with the parent class.
200             # Trigger a side effect.
201             #if (exists $this->{'-sideeffect'}->{$AUTOLOAD})
202             #{
203             # &{$this->{'-sideeffect'}->{$AUTOLOAD}}($this);
204             #}
205             }
206            
207 20         586 $this->{$AUTOLOAD};
208             }
209              
210             =pod
211              
212             =head1 SEE ALSO
213              
214             Config::Nested
215              
216             =head1 COPYRIGHT
217              
218             Copyright (c) 1998-2008 Anthony Fletcher. All rights reserved.
219             These modules are free software; you can redistribute them and/or modify
220             them under the same terms as Perl itself.
221              
222             This code is supplied as-is - use at your own risk.
223              
224             =head1 AUTHOR
225              
226             Anthony Fletcher
227              
228             =cut
229              
230             ###################################
231              
232             sub test
233             {
234 0     0 0   my $obj = new Config::Nested::Section(
235             list => [],
236             path => [],
237             owner => '',
238             location=> '',
239             colour => {},
240             contents=> [],
241             hash1 => {},
242             hash2 => {},
243             number => 3,
244             firstname=> '',
245             surname => '',
246             );
247 0           print "obj = ", Dumper($obj);
248              
249 0           $obj->owner('Fred');
250 0           $obj->location('here');
251 0           $obj->list(qw(a b c d e));
252              
253 0           my $obj2 = dclone($obj);
254 0           my $obj3 = $obj->new(scalar => 'name');
255              
256 0           $obj2->owner('Harold');
257              
258 0           unshift @{$obj->list}, 'zero';
  0            
259 0           $obj2->colour->{head} = 'blue';
260              
261 0           print "obj = ", Dumper($obj);
262 0           print "obj2= ", Dumper($obj2);
263 0           print "obj3= ", Dumper($obj3);
264              
265             #eval { $obj->job; }; print $@;
266              
267 0           my $b = new Config::Nested::Section(path => [], contact => {});
268 0           $b->path->[0] ='first step';
269 0           $b->contact->{'parent'} ='Mum';
270 0           print "b=", Dumper($b);
271              
272             # Register side effect for 'owner'.
273             #$obj->{-sideeffect}->{owner} = sub {
274             #
275             # my ($this) = @_;
276             # my ($firstname, @names) = split(/\s+/, $this->owner());
277             # if (@names)
278             # {
279             # $this->firstname($firstname);
280             # $this->surname(pop(@names));
281             # }
282             # else
283             # {
284             # $this->firstname('');
285             # $this->surname('');
286             # }
287             #
288             # 1;
289             #};
290             #
291             #$obj->owner('Fred Smith');
292             #print "\nobj = ", Dumper($obj);
293             #
294             # Doesn't work! dclone won't copy CODE.
295             #my $obj5 = dclone($obj);
296              
297             }
298              
299             &test if ( __FILE__ eq $0);
300              
301             1;
302              
303