File Coverage

blib/lib/Config/YAML.pm
Criterion Covered Total %
statement 73 81 90.1
branch 19 26 73.0
condition 7 11 63.6
subroutine 11 14 78.5
pod 6 6 100.0
total 116 138 84.0


line stmt bran cond sub pod time code
1             package Config::YAML;
2              
3             # $Id: YAML.pm 41 2005-03-15 22:33:09Z mdxi $
4              
5 7     7   230408 use warnings;
  7         17  
  7         264  
6 7     7   39 use strict;
  7         12  
  7         232  
7 7     7   6462 use YAML;
  7         111053  
  7         483  
8              
9 7     7   76 use vars qw( $AUTOLOAD );
  7         15  
  7         2683  
10              
11             =head1 NAME
12              
13             Config::YAML - Simple configuration automation
14              
15             =head1 VERSION
16              
17             Version 1.42
18              
19             =cut
20              
21             our $VERSION = '1.42';
22              
23             =head1 SYNOPSIS
24              
25             Config::YAML is a somewhat object-oriented wrapper around the YAML
26             module which makes reading and writing configuration files
27             simple. Handling multiple config files (e.g. system and per-user
28             configuration, or a gallery app with per-directory configuration) is a
29             snap.
30              
31             use Config::YAML;
32              
33             # create Config::YAML object with any desired initial options
34             # parameters; load system config; set alternate output file
35             my $c = Config::YAML->new( config => "/usr/share/foo/globalconf",
36             output => "~/.foorc",
37             param1 => value1,
38             param2 => value2,
39             ...
40             paramN => valueN,
41             );
42              
43             # integrate user's own config
44             $c->read("~/.foorc");
45              
46             # integrate command line args using Getopt::Long
47             $rc = GetOptions ( $c,
48             'param1|p!',
49             'param2|P',
50             'paramN|n',
51             );
52              
53             # Write configuration state to disk
54             $c->write;
55              
56             # simply get params back for use...
57             do_something() unless $c->{param1};
58             # or get them more OO-ly if that makes you feel better
59             my $value = $c->get_param2;
60              
61             =cut
62              
63              
64              
65              
66             =head1 METHODS
67              
68             =head2 new
69              
70             Creates a new Config::YAML object.
71              
72             my $c = Config::YAML->new( config => initial_config,
73             output => output_config
74             );
75              
76             The C parameter specifies the file to be read in during object
77             creation. It is required, and must be the first parameter given. If
78             the second parameter is C, then it is used to specify the file
79             to which configuration data will later be written out. This
80             positional dependancy makes it possible to have parameters named
81             "config" and/or "output" in config files.
82              
83             Initial configuration values can be passed as subsequent parameters to
84             the constructor:
85              
86             my $c = Config::YAML->new( config => "~/.foorc",
87             foo => "abc",
88             bar => "xyz",
89             baz => [ 1, 2, 3 ],
90             );
91              
92             =cut
93              
94             sub new {
95 9     9 1 6148 my $class = shift;
96 9         28 my %priv = ();
97 9         22 my %args = ();
98              
99 9 50       50 die("Can't create Config::YAML object with no config file.\n")
100             if ($_[0] ne "config");
101 9         17 shift; $priv{config} = shift;
  9         28  
102              
103 9 100 66     69 if (@_ && ($_[0] eq "output")) { shift; $priv{output} = shift; }
  2         5  
  2         7  
104 9 50 66     46 if (@_ && ($_[0] eq "strict")) { shift; $priv{strict} = shift; }
  0         0  
  0         0  
105              
106 9   66     150 my $self = bless { _infile => $priv{config},
      50        
107             _outfile => $priv{output} || $priv{config},
108             _strict => $priv{strict} || 0,
109             }, $class;
110              
111 9         25 %args = @_;
112 9         25 @{$self}{keys %args} = values %args;
  9         47  
113              
114 9         46 $self->read;
115 9         90 return $self;
116             }
117              
118             =head2 get_*/set_*
119              
120             If you'd prefer not to directly molest the object to store and
121             retrieve configuration data, autoloading methods of the forms
122             C and C are provided. Continuing from the
123             previous example:
124              
125             print $c->get_foo; # prints "abc"
126             my $val = $c->get_quux; # $c->{quux} doesn't exist; returns undef
127              
128             $c->set_bar(30); # $c->{bar} now equals 30, not "xyz"
129             my @list = qw(alpha beta gamma);
130             $c->set_baz(\@list); # $c->{baz} now a reference to @list
131              
132             =cut
133              
134             sub Config::YAML::AUTOLOAD {
135 7     7   43 no strict 'refs';
  7         15  
  7         6276  
136 7     7   1612 my ($self, $newval) = @_;
137              
138 7 100       27 if ($AUTOLOAD =~ /.*::get_(\w+)/) {
139 4         9 my $attr = $1;
140 4 100       14 return undef if (!defined $self->{$attr});
141 3     1   11 *{$AUTOLOAD} = sub { return $_[0]->{$attr} };
  3         14  
  1         5  
142 3         19 return $self->{$attr};
143             }
144              
145 3 50       16 if ($AUTOLOAD =~ /.*::set_(\w+)/) {
146 3         6 my $attr = $1;
147 3     0   10 *{$AUTOLOAD} = sub { $_[0]->{$attr} = $_[1]; return };
  3         10  
  0         0  
  0         0  
148 3         32 $self->{$attr} = $newval;
149 3         6 return;
150             }
151             }
152              
153             =head2 fold
154              
155             Convenience method for folding multiple values into the config object
156             at once. Requires a hashref as its argument.
157              
158             $prefs{theme} = param(theme);
159             $prefs{format} = param(format);
160             $prefs{sortby} = param(order);
161              
162             $c->fold(\%prefs);
163              
164             my $format = $c->get_format; # value matches that of param(format)
165              
166             =cut
167              
168             sub fold {
169 1     1 1 8 my ($self, $data) = @_;
170             # add check for HASHREF when strict mode is implemented
171 1         2 @{$self}{keys %{$data}} = values %{$data};
  1         5  
  1         3  
  1         4  
172             }
173              
174             =head2 read
175              
176             Imports a YAML-formatted config file.
177              
178             $c->read('/usr/share/fooapp/fooconf');
179              
180             C is called at object creation and imports the file specified
181             by C<< new(config=>) >>, so there is no need to call it manually
182             unless multiple config files exist.
183              
184             =cut
185              
186             sub read {
187 10     10 1 1067 my ($self, $file) = @_;
188 10 100       35 $self->{_infile} = $file if $file;
189              
190 10         17 my $yaml;
191             my $line;
192              
193 10 50       552 open(FH,'<',$self->{_infile}) or die "Can't open $self->{_infile}; $!\n";
194 10         321 while ($line = ) {
195 190 100       408 next if ($line =~ /^\-{3,}/);
196 181 50       290 next if ($line =~ /^#/);
197 181 50       339 next if ($line =~ /^$/);
198 181         499 $yaml .= $line;
199             }
200 10         116 close(FH);
201              
202 10         57 my $tmpyaml = Load($yaml);
203 10         193452 @{$self}{keys %{$tmpyaml}} = values %{$tmpyaml}; # woo, hash slice
  10         101  
  10         34  
  10         49  
204             }
205              
206             =head2 write
207              
208             Dump current configuration state to a YAML-formatted flat file.
209              
210             $c->write;
211              
212             The file to be written is specified in the constructor call. See the
213             C method documentation for details.
214              
215             =cut
216              
217             sub write {
218 1     1 1 6 my $self = shift;
219 1         2 my %tmpyaml;
220              
221             # strip out internal state parameters
222 1         2 while(my($k,$v) = each%{$self}) {
  15         46  
223 14 100       41 $tmpyaml{$k} = $v unless ($k =~ /^_/);
224             }
225              
226             # write data out to file
227 1 50       136 open(FH,'>',$self->{_outfile}) or die "Can't open $self->{_outfile}: $!\n";
228 1         6 print FH Dump(\%tmpyaml);
229 1         22866 close(FH);
230             }
231              
232             =head1 DEPRECATED METHODS
233              
234             These methods have been superceded and will likely be removed in the
235             next release.
236              
237             =head2 get
238              
239             Returns the value of a parameter.
240              
241             print $c->get('foo');
242              
243             =cut
244              
245             sub get {
246 0     0 1   my ($self, $arg) = @_;
247 0           return $self->{$arg};
248             }
249              
250             =head2 set
251              
252             Sets the value of a parameter:
253              
254             $c->set('foo',1);
255              
256             my @paints = qw( oil acrylic tempera );
257             $c->set('paints', \@paints);
258              
259             =cut
260              
261             sub set {
262 0     0 1   my ($self, $key, $val) = @_;
263 0           $self->{$key} = $val;
264             }
265              
266             =head1 AUTHOR
267              
268             Shawn Boyette (C<< >>)
269              
270             Original implementation by Kirrily "Skud" Robert (as
271             C).
272              
273             =head1 BUGS
274              
275             =over
276              
277             =item
278              
279             Config::YAML ignores the YAML document separation string (C<--->)
280             because it has no concept of multiple targets for the data coming from
281             a config file.
282              
283             =back
284              
285             Please report any bugs or feature requests to
286             C, or through the web interface at
287             L. I will be notified, and then you'll
288             automatically be notified of progress on your bug as I make changes.
289              
290             =head1 COPYRIGHT & LICENSE
291              
292             Copyright 2004 Shawn Boyette, All Rights Reserved.
293              
294             This program is free software; you can redistribute it and/or modify
295             it under the same terms as Perl itself.
296              
297             =cut
298              
299             1; # End of Config::YAML