File Coverage

/.cpan/build/Config-Abstract-0.16-7ag85k/blib/lib/Config/Abstract.pm
Criterion Covered Total %
statement 15 135 11.1
branch 0 46 0.0
condition 0 9 0.0
subroutine 5 27 18.5
pod 10 15 66.6
total 30 232 12.9


line stmt bran cond sub pod time code
1             package Config::Abstract;
2              
3 1     1   12 use 5.006;
  1         3  
  1         30  
4 1     1   4 use strict;
  1         1  
  1         20  
5 1     1   4 use warnings;
  1         1  
  1         17  
6              
7 1     1   834 use Data::Dumper;
  1         10189  
  1         90  
8              
9             require Exporter;
10             #use AutoLoader qw(AUTOLOAD);
11              
12 1     1   8 use overload qw{""} => \&_to_string;
  1         1  
  1         5  
13              
14             our @ISA = qw(Exporter);
15             our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );
16             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
17             our @EXPORT = qw( );
18              
19             our $VERSION = '0.16';
20              
21             #
22             # ------------------------------------------------------------------------------------------------------- structural methods -----
23             #
24              
25             sub new {
26 0     0 0   my($class,$initialiser) = @_;
27 0           my $self = {
28             _settings => undef,
29             _settingsfile => undef
30             };
31 0   0       bless $self,ref $class || $class;
32 0           $self->init($initialiser);
33 0           return $self;
34             }
35              
36             sub init {
37 0     0 0   my($self,$settingsfile) = @_;
38 0 0         return unless(defined($settingsfile));
39 0 0         return if($settingsfile eq '');
40 0           $self->{_settings} = $self->_read_settings($settingsfile);
41 0           $self->{_settingsfile} = $settingsfile;
42             }
43              
44              
45             #
46             # --------------------------------------------------------------------------------------------------------- accessor methods -----
47             #
48              
49             sub get_all_settings {
50 0     0 1   my($self) = @_;
51             # Make sure we don't crash and burn trying to return a hash from an undef reference
52 0 0         return undef unless(defined($self->{_settings}));
53             # Return the settings as a hash in array contect and a hash reference in scalar context
54 0 0         if(wantarray){
55 0           return %{$self->{_settings}};
  0            
56             }else{
57 0           return $self->{_settings};
58             }
59             }
60              
61             sub get_entry {
62 0     0 1   my($self,$entryname) = @_;
63 0           my $val;
64 0 0         if($entryname =~ m|//|){
65             # Getting an entry by path
66 0           my $unpathed = $self->_unpath($entryname);
67 0           eval("\$val = \"\${ \$self->{_settings} }$unpathed\";");
68             # print("\$val = '\${ \$self->{_settings} }$unpathed ';\n");#DEBUG!!!
69             # print("\$val: $val\n");#DEBUG!!!
70             }else{
71 0           $val = ${$self->{_settings}}{$entryname};
  0            
72             }
73 0 0         if(defined($val)){
74 0 0 0       if(wantarray && ref($val) eq 'HASH'){
75             # print STDERR ("Returning HASH in $self" . "->get_entry($entryname)\n");#DEBUG!!!
76 0           return(%{$val});
  0            
77             }else{
78             # print STDERR ("Returning ref in $self" . "->get_entry($entryname)\n");#DEBUG!!!
79 0           return($val);
80             }
81             }else{
82 0 0         return (wantarray ? () : undef);
83             }
84             }
85              
86             sub get_entry_setting {
87 0     0 1   my($self,$entryname,$settingname,$default) = @_;
88             # Return undef if the requested entry doesn't exist
89 0           my %entry = ();
90 0 0         return(undef) unless(%entry = $self->get_entry($entryname));
91 0 0         if(defined($entry{$settingname})){
92 0           return $entry{$settingname};
93             }else{
94 0           return $default;
95             }
96             }
97              
98             sub get {
99 0     0 1   my($self,$section,$key,$default) = @_;
100             # If everything up to the key is given, get a specific key
101 0 0         return $self->get_entry_setting($section,$key,$default) if(defined($key));
102             # If section is given, but not key, get a specific section
103 0 0         return $self->get_entry($section) if(defined($section));
104             # If no parameter is given, return the entire hash
105 0           return $self->get_all_settings();
106             }
107              
108             #
109             # ---------------------------------------------------------------------------------------------------------- mutator methods -----
110             #
111              
112             sub set_all_settings {
113 0     0 1   my($self,%allsettings) = @_;
114 0           return %{$self->{_settings}} = %allsettings;
  0            
115             }
116              
117             sub set_entry {
118 0     0 1   my($self,$entryname,$entry) = @_;
119 0           my $unpathed = $self->_unpath($entryname);
120 0           my $val;
121 0           eval('${$self->{_settings}}' . $unpathed . ' = $entry;');
122 0           return $self->get_entry($entryname) ;
123             }
124              
125             sub set_entry_setting {
126 0     0 1   my($self,$entryname,$settingname,$setting) = @_;
127 0           return (${${$self->{_settings}}{$entryname}}{$settingname} = $setting);
  0            
  0            
128             }
129              
130             sub set {
131 0     0 1   my($self,$section,$key,$value) = @_;
132             # If everything up to the key is given, set a specific key
133 0 0         return $self->set_entry_setting($section,$key,$value) if(defined($value));
134             # If section is given, but not key, set a specific section
135 0 0         return $self->set_entry($section,$key) if(defined($key));
136             # If no parameter is given, return the entire hash
137 0           return $self->set_all_settings(%{$section});
  0            
138             }
139              
140             sub exists {
141 0     0 0   my($self,$section,$key) = @_;
142 0 0         return defined($self->{$section}) unless (defined($key));
143 0           return defined($self->{$section}{$key});
144             }
145              
146             sub get_entry_names {
147 0     0 0   my($self) = @_;
148 0           return sort(keys(%{$self->{_settings}}));
  0            
149             }
150              
151             #
152             # ------------------------------------------------------------------------------------------------------- arithmetic methods -----
153             #
154              
155             ##################################################
156             #%name: diff
157             #%syntax: diff($other_config_object)
158             #%summary: Generates an object with overrides for entries that can be used to patch $self into $other_config_object
159             #%returns: a Config::Abstract object
160             #%NB: This method is nowhere near working atm /EWT
161             sub diff {
162 0     0 1   my($self,$diff) = @_;
163 0           my %self_pathed = $self->_pathalise_object( '',$self->{_settings} );
164 0           my %diff_pathed = $self->_pathalise_object( '',$diff->{_settings} );
165 0           my $result = $self->new();
166 0           while( my($k,$v) = each(%diff_pathed) ) {
167 0 0 0       next if( defined($self_pathed{$k}) && $self_pathed{$k} eq $v);
168 0           $result->set($k,$v);
169             }
170 0           return $result;
171             }
172              
173              
174             ##################################################
175             #%name: patch
176             #%syntax: patch($patch_from_other_config_object)
177             #%summary: Overrides all settings that are found in the $patch object with the $patch values
178             #%returns: Nothing
179             sub patch {
180 0     0 1   my($self,$patch) = @_;
181 0           my %patch_pathed = $self->_pathalise_object( '',$patch->{_settings} );
182 0           while( my($k,$v) = each(%patch_pathed) ) {
183 0           $self->set($k,$v);
184             }
185             }
186              
187              
188              
189             sub _unpath {
190 0     0     my($self,$path) = @_;
191 0           $path =~ s|^/+|{'|;
192 0           $path =~ s|/+|'}{'|g;
193 0           $path .= '\'}';
194 0           return $path;
195             }
196             ##################################################
197             #%name: _pathalise_object
198             #%syntax: _dumpobject(<$objectcaption>,<$objectref>,[<@parentobjectcaptions>])
199             #%summary: Recursively generates a string representation of the object referenced
200             # by $objectref
201             #%returns: a string representation of the object
202              
203             sub _pathalise_object{
204 0     0     my($self,$name,$obj,@parents) = @_;
205 0           my @result = ();
206 0 0         if(ref($obj) eq 'HASH'){
    0          
    0          
207 0 0         unless($name eq '' ){
208 0           push(@parents,$name);
209             }
210 0           while(my($key,$val) = each(%{$obj})){
  0            
211 0           push(@result,$self->_pathalise_object($key,$val,@parents));
212             }
213             }elsif(ref($obj) eq 'SCALAR'){
214 0           push(@result,'//' . join('//',@parents) . "//$name",${$obj});
  0            
215             }elsif(ref($obj) eq 'ARRAY'){
216 0           push(@parents,$name);
217 0           for(my $i = 0;scalar(@{$obj});$i++){
  0            
218 0           push(@result,$self->_pathalise_object($i,${$obj}[$i],@parents));
  0            
219             }
220             }else{
221 0           push(@result,'//' . join('//',@parents) . "//$name",$obj);
222             }
223 0           return @result;
224             }
225             #
226             # ------------------------------------------------------------------------------------------------ (de)serialisation methods -----
227             #
228              
229             ##################################################
230             #%name: _to_string
231             #%syntax: _to_string
232             #%summary: Recursively generates a string representation of the settings hash
233             #%returns: a string in perl source format
234              
235             sub _to_string{
236 0     0     my($self) = @_;
237 0           return $self->_dumpobject();
238             }
239              
240             ##################################################
241             #%name: _dumpobject
242             #%syntax: _dumpobject(<$objectcaption>,<$objectref>,[<@parentobjectcaptions>])
243             #%summary: Generates a string representation of the object referenced
244             # by $objectref
245             #%returns: a string representation of the object
246              
247             sub _dumpobject{
248 0     0     my($self) = @_;
249 0           my $dumper = Data::Dumper->new([$self->{_settings}],[qw(settings)]);
250 0           $dumper->Purity(1);
251 0           return($dumper->Dump());
252             }
253              
254             ##################################################
255             #%name: _read_settings
256             #%syntax: _read_settings(<$settingsfilename>)
257             #%summary: Reads the key-values to keep track of
258             #%returns: a reference to a hash of $key:$value
259              
260             sub _read_settings{
261 0     0     my ($self,$settingdata) = @_;
262 0           my @conflines;
263 0 0         if(ref($settingdata) eq 'ARRAY'){
264 0           @conflines = @{$settingdata};
  0            
265             }else{
266 0           my $settingsfile = $settingdata;
267             # Read in the ini file we want to use
268             # Probably not a good idea to die on error at this
269             # point, but that's what we've got for the moment
270 0 0         open(SETTINGS,$settingsfile) || die("Failed to open ini file ($settingsfile) for reading\n");
271 0           @conflines = ;
272 0           close(SETTINGS);
273             }
274 0           my $settings = $self->_parse_settings_file(@conflines);
275 0           return($settings);
276             }
277              
278             ##################################################
279             #%name: _parse_settings_file
280             #%syntax: _parse_settings_file(<@settings>)
281             #%summary: Reads the key-values into a hash
282             #%returns: a reference to a hash of $key:$value
283              
284             sub _parse_settings_file{
285 0     0     my $settings = {};
286 0           eval(join('',@_));
287 0           return($settings);
288             }
289              
290             #
291             # ---------------------------------------------------------------------------------------------------------- utility methods -----
292             #
293              
294              
295             sub expand_tilde {
296 0 0   0 0   defined($ENV{'HOME'}) && do {
297 0           $_[0] =~ s/^~/$ENV{'HOME'}/;
298             };
299 0           return $_[0];
300             }
301              
302              
303             # We provide a DESTROY method so that the autoloader
304             # doesn't bother trying to find it.
305             sub DESTROY {
306 0     0     print STDERR ("Destroying Config::Abstract\n"); #DEBUG!!!
307             }
308              
309             1;
310             __END__