File Coverage

blib/lib/Config/Tiny.pm
Criterion Covered Total %
statement 52 56 92.9
branch 21 32 65.6
condition 1 2 50.0
subroutine 9 11 81.8
pod 6 6 100.0
total 89 107 83.2


line stmt bran cond sub pod time code
1             package Config::Tiny;
2              
3             # If you thought Config::Simple was small...
4              
5 2     2   49 use 5.004;
  2         18  
  2         19  
6 2     2   31 use strict;
  2         18  
  2         31  
7              
8 2     2   29 use vars qw{$VERSION $errstr};
  2         19  
  2         31  
9             BEGIN {
10 2     2   70 $VERSION = '2.10';
11 2         21 $errstr  = '';
12             }
13              
14             # Create an empty object
15 1     1 1 15 sub new { bless {}, shift }
16              
17             # Create an object from a file
18             sub read {
19 2 50   2 1 25 my $class = ref $_[0] ? ref shift : shift;
20              
21             # Check the file
22 2 50       23 my $file = shift or return $class->_error( 'You did not specify a file name' );
23 2 50       147 return $class->_error( "File '$file' does not exist" ) unless -e $file;
24 2 50       24 return $class->_error( "'$file' is a directory, not a file" ) unless -f _;
25 2 50       22 return $class->_error( "Insufficient permissions to read '$file'" ) unless -r _;
26              
27             # Slurp in the file
28 2         24 local $/ = undef;
29 2 50       120 open CFG, $file or return $class->_error( "Failed to open file '$file': $!" );
30 2         17636 my $contents = <CFG>;
31 2         65 close CFG;
32              
33 2         30 $class->read_string( $contents );
34             }
35              
36             # Create an object from a string
37             sub read_string {
38 5 50   5 1 89 my $class = ref $_[0] ? ref shift : shift;
39 5         64 my $self = bless {}, $class;
40 5 50       53 return undef unless defined $_[0];
41              
42             # Parse the file
43 5         92 my $ns = '_';
44 5         42 my $counter = 0;
45 5         196 foreach ( split /(?:\015{1,2}\012|\015|\012)/, shift ) {
46 39         322 $counter++;
47              
48             # Skip comments and empty lines
49 39 100       1893 next if /^\s*(?:\#|\;|$)/;
50              
51             # Handle section headers
52 29 100       334 if ( /^\s*\[\s*(.+?)\s*\]\s*$/ ) {
53             # Create the sub-hash if it doesn't exist.
54             # Without this sections without keys will not
55             # appear at all in the completed struct.
56 9   50     151 $self->{$ns = $1} ||= {};
57 9         87 next;
58             }
59              
60             # Handle properties
61 20 50       293 if ( /^\s*([^=]+?)\s*=\s*(.*?)\s*$/ ) {
62 20         260 $self->{$ns}->{$1} = $2;
63 20         186 next;
64             }
65              
66 0         0 return $self->_error( "Syntax error at line $counter: '$_'" );
67             }
68              
69 5         72 $self;
70             }
71              
72             # Save an object to a file
73             sub write {
74 1     1 1 10 my $self = shift;
75 1 50       14 my $file = shift or return $self->_error(
76             'No file name provided'
77             );
78              
79             # Write it to the file
80 1 50       152 open( CFG, '>' . $file ) or return $self->_error(
81             "Failed to open file '$file' for writing: $!"
82             );
83 1         14 print CFG $self->write_string;
84 1         390 close CFG;
85             }
86              
87             # Save an object to a string
88             sub write_string {
89 2     2 1 20 my $self = shift;
90              
91 2         19 my $contents = '';
92 2 100       24 foreach my $section ( sort { (($b eq '_') <=> ($a eq '_')) || ($a cmp $b) } keys %$self ) {
  6         78  
93 6         3547 my $block = $self->{$section};
94 6 100       3163 $contents .= "\n" if length $contents;
95 6 100       157 $contents .= "[$section]\n" unless $section eq '_';
96 6         91 foreach my $property ( sort keys %$block ) {
97 10         132 $contents .= "$property=$block->{$property}\n";
98             }
99             }
100            
101 2         73 $contents;
102             }
103              
104             # Error handling
105 0     0 1   sub errstr { $errstr }
106 0     0     sub _error { $errstr = $_[1]; undef }
  0            
107              
108             1;
109              
110             __END__
111            
112             =pod
113            
114             =head1 NAME
115            
116             Config::Tiny - Read/Write .ini style files with as little code as possible
117            
118             =head1 SYNOPSIS
119            
120             # In your configuration file
121             rootproperty=blah
122            
123             [section]
124             one=twp
125             three= four
126             Foo =Bar
127             empty=
128            
129             # In your program
130             use Config::Tiny;
131            
132             # Create a config
133             my $Config = Config::Tiny->new();
134            
135             # Open the config
136             $Config = Config::Tiny->read( 'file.conf' );
137            
138             # Reading properties
139             my $rootproperty = $Config->{_}->{rootproperty};
140             my $one = $Config->{section}->{one};
141             my $Foo = $Config->{section}->{Foo};
142            
143             # Changing data
144             $Config->{newsection} = { this => 'that' }; # Add a section
145             $Config->{section}->{Foo} = 'Not Bar!'; # Change a value
146             delete $Config->{_}; # Delete a value or section
147            
148             # Save a config
149             $Config->write( 'file.conf' );
150            
151             =head1 DESCRIPTION
152            
153             C<Config::Tiny> is a perl class to read and write .ini style configuration
154             files with as little code as possible, reducing load time and memory
155             overhead. Most of the time it is accepted that Perl applications use a lot
156             of memory and modules. The C<::Tiny> family of modules is specifically
157             intended to provide an ultralight alternative to the standard modules.
158            
159             This module is primarily for reading human written files, and anything we
160             write shouldn't need to have documentation/comments. If you need something
161             with more power move up to L<Config::Simple>, L<Config::General> or one of
162             the many other C<Config::> modules. To rephrase, L<Config::Tiny> does B<not>
163             preserve your comments, whitespace, or the order of your config file.
164            
165             =head1 CONFIGURATION FILE SYNTAX
166            
167             Files are the same format as for windows .ini files. For example:
168            
169             [section]
170             var1=value1
171             var2=value2
172            
173             If a property is outside of a section at the beginning of a file, it will
174             be assigned to the C<"root section">, available at C<$Config-E<gt>{_}>.
175            
176             Lines starting with C<'#'> or C<';'> are considered comments and ignored,
177             as are blank lines.
178            
179             When writing back to the config file, all comments, custom whitespace,
180             and the ordering of your config file elements is discarded. If you need
181             to keep the human elements of a config when writing back, upgrade to
182             something better, this module is not for you.
183            
184             =head1 METHODS
185            
186             =head2 new
187            
188             The constructor C<new> creates and returns an empty C<Config::Tiny> object.
189            
190             =head2 read $filename
191            
192             The C<read> constructor reads a config file, and returns a new
193             C<Config::Tiny> object containing the properties in the file.
194            
195             Returns the object on success, or C<undef> on error.
196            
197             When C<read> fails, C<Config::Tiny> sets an error message internally
198             you can recover via C<<Config::Tiny->errstr>>. Although in B<some>
199             cases a failed C<read> will also set the operating system error
200             variable C<$!>, not all errors do and you should not rely on using
201             the C<$!> variable.
202            
203             =head2 read_string $string;
204            
205             The C<read_string> method takes as argument the contents of a config file
206             as a string and returns the C<Config::Tiny> object for it.
207            
208             =head2 write $filename
209            
210             The C<write> method generates the file content for the properties, and
211             writes it to disk to the filename specified.
212            
213             Returns true on success or C<undef> on error.
214            
215             =head2 write_string
216            
217             Generates the file content for the object and returns it as a string.
218            
219             =head2 errstr
220            
221             When an error occurs, you can retrieve the error message either from the
222             C<$Config::Tiny::errstr> variable, or using the C<errstr()> method.
223            
224             =head1 SUPPORT
225            
226             Bugs should be reported via the CPAN bug tracker at
227            
228             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Config-Tiny>
229            
230             For other issues, or commercial enhancement or support, contact the author.
231            
232             =head1 AUTHOR
233            
234             Adam Kennedy E<lt>adamk@cpan.orgE<gt>
235            
236             =head1 ACKNOWLEGEMENTS
237            
238             Thanks to Sherzod Ruzmetov E<lt>sherzodr@cpan.orgE<gt> for
239             L<Config::Simple>, which inspired this module by being not quite
240             "simple" enough for me :)
241            
242             =head1 SEE ALSO
243            
244             L<Config::Simple>, L<Config::General>, L<ali.as>
245            
246             =head1 COPYRIGHT
247            
248             Copyright 2002 - 2006 Adam Kennedy.
249            
250             This program is free software; you can redistribute
251             it and/or modify it under the same terms as Perl itself.
252            
253             The full text of the license can be found in the
254             LICENSE file included with this module.
255            
256             =cut
257