File Coverage

blib/lib/Config/Tiny/Ordered.pm
Criterion Covered Total %
statement 26 37 70.2
branch 7 16 43.7
condition 1 2 50.0
subroutine 5 6 83.3
pod 3 3 100.0
total 42 64 65.6


line stmt bran cond sub pod time code
1             package Config::Tiny::Ordered;
2              
3             # If you thought Config::Tiny was small...
4              
5 3     3   75425 use base 'Config::Tiny';
  3         13  
  3         1990  
6 3     3   3802 use strict;
  3         8  
  3         151  
7              
8             our $VERSION = '1.03';
9              
10             BEGIN
11             {
12 3     3   58 require 5.004;
13              
14 3         1687 $Config::Tiny::Ordered::errstr = '';
15             }
16              
17             # Create an empty object.
18              
19             sub new
20             {
21 1     1 1 844 return $_[0] -> SUPER::new();
22             }
23              
24             # Create an object from a string.
25              
26             sub read_string
27             {
28 4 50   4 1 8437 my($class) = ref $_[0] ? ref shift : shift;
29 4         11 my($self) = bless {}, $class;
30              
31 4 50       12 return undef unless defined $_[0];
32              
33             # Parse the data.
34              
35 4         7 my $ns = '_';
36 4         5 my $counter = 0;
37              
38 4         88 for (split /(?:\015{1,2}\012|\015|\012)/, shift)
39             {
40 31         43 $counter++;
41              
42             # Skip comments and empty lines.
43              
44 31 100       77 next if /^\s*(?:\#|\;|$)/;
45              
46             # Remove inline comments.
47              
48 23         43 s/\s\;\s.+$//g;
49              
50             # Handle section headers.
51              
52 23 100       58 if ( /^\s*\[\s*(.+?)\s*\]\s*$/ )
53             {
54             # Create the sub-hash if it doesn't exist.
55             # Without this sections without keys will not
56             # appear at all in the completed struct.
57              
58 7   50     53 $self->{$ns = $1} ||= [];
59              
60 7         14 next;
61             }
62              
63             # Handle properties.
64              
65 16 50       72 if ( /^\s*([^=]+?)\s*=\s*(.*?)\s*$/ )
66             {
67 16         21 push @{$self->{$ns} }, {key => $1, value => $2};
  16         73  
68 16         30 next;
69             }
70              
71 0         0 return $self->_error( "Syntax error at line $counter: '$_'" );
72             }
73              
74 4         15 return $self;
75              
76             } # End of read_string.
77              
78             # Save an object to a string.
79              
80             sub write_string
81             {
82 0     0 1   my($self) = shift;
83              
84 0           my $contents = '';
85              
86 0 0         for my $section (sort { (($b eq '_') <=> ($a eq '_')) || ($a cmp $b) } keys %$self)
  0            
87             {
88 0           my $block = $self->{$section};
89 0 0         $contents .= "\n" if length $contents;
90 0 0         $contents .= "[$section]\n" unless $section eq '_';
91              
92 0           for my $property ( @$block )
93             {
94 0           $contents .= "$$property{'key'}=$$property{'value'}\n";
95             }
96             }
97              
98 0           return $contents;
99              
100             } # End of write_string.
101              
102             1;
103              
104             =pod
105              
106             =head1 NAME
107              
108             Config::Tiny::Ordered - Read/Write ordered .ini style files with as little code as possible
109              
110             =head1 SYNOPSIS
111              
112             # In your configuration file:
113             rootproperty=blah
114              
115             [section]
116             reg_exp_1=High Priority
117             reg_exp_2=Low Priority
118             three= four
119             Foo =Bar
120             empty=
121              
122             # In your program:
123             use Config::Tiny::Ordered;
124              
125             # Create a config:
126             my $Config = Config::Tiny::Ordered->new();
127              
128             # Open the config:
129             $Config = Config::Tiny::Ordered->read( 'file.conf' );
130              
131             # Reading properties:
132             my $rootproperty = $Config->{_}->{rootproperty};
133             my $section = $Config->{section}; # An arrayref of hashrefs,
134             my $key = $$section[0]{'key'}; # where the format is:
135             my $re1 = $$section[0]{'value'}; # [{key => ..., value => ...},
136             my $re2 = $$section[1]{'value'}; # {key => ..., value => ...},
137             my $Foo = $$section[3]{'value'}; # ...].
138              
139             # Changing data:
140             $Config->{newsection} = { this => 'that' }; # Add a section
141             $Config->{section}->{Foo} = 'Not Bar!'; # Change a value
142             delete $Config->{_}; # Delete a value or section
143              
144             # Save a config:
145             $Config->write( 'new.conf' );
146              
147             =head1 DESCRIPTION
148              
149             C is a perl class to read and write .ini style configuration
150             files with as little code as possible.
151              
152             Read more in the docs for C.
153              
154             This module is primarily for reading human written files, and anything we
155             write shouldn't need to have documentation/comments. If you need something with more power,
156             move up to L, L, L, L or one of
157             the many other C modules.
158              
159             Note: L does B preserve your comments or whitespace.
160              
161             This module differs from C in that here the data within a section is stored
162             in memory in the same order as it appears in the input file or string.
163              
164             C does this by storing the keys and values in an arrayref
165             rather than, as most config modules do, in a hashref.
166              
167             This arrayref consists of an ordered set of hashrefs, and these hashrefs use the keys
168             'key' and 'value'.
169              
170             So, in memory, the data in the synopsis, for the section called 'section', looks like:
171              
172             [
173             {key => 'reg_exp_1', value => 'High Priority'},
174             {key => 'reg_exp_2', vlaue => 'Low Priority'},
175             etc
176             ]
177              
178             This means the config file can be used in situations such as with business rules
179             which must be applied in a specific order.
180              
181             =head1 CONFIGURATION FILE SYNTAX
182              
183             Files are the same format as for windows .ini files. For example:
184              
185             [section]
186             var1=value1
187             var2=value2
188              
189             If a property is outside of a section at the beginning of a file, it will
190             be assigned to the C<"root section">, available at C<$Config-E{_}>.
191              
192             Lines starting with C<'#'> or C<';'> are considered comments and ignored,
193             as are blank lines.
194              
195             =head1 METHODS
196              
197             =head2 new
198              
199             The constructor C creates and returns an empty C object.
200              
201             =head2 read $filename
202              
203             The C constructor reads a config file, and returns a new
204             C object containing the properties in the file.
205              
206             Returns the object on success, or C on error.
207              
208             When C fails, C sets an error message internally,
209             which you can recover via C<errstr>>. Although in B
210             cases a failed C will also set the operating system error
211             variable C<$!>, not all errors do and you should not rely on using
212             the C<$!> variable.
213              
214             =head2 read_string $string;
215              
216             The C method takes, as an argument, the contents of a config file
217             as a string and returns the C object for it.
218              
219             =head2 write $filename
220              
221             The C method generates the file content for the properties, and
222             writes it to disk to the filename specified.
223              
224             Returns true on success or C on error.
225              
226             =head2 write_string
227              
228             Generates the file content for the object and returns it as a string.
229              
230             =head2 errstr
231              
232             When an error occurs, you can retrieve the error message either from the
233             C<$Config::Tiny::Ordered::errstr> variable, or using the C method.
234              
235             =head1 Repository
236              
237             L
238              
239             =head1 SUPPORT
240              
241             Bugs should be reported via the CPAN bug tracker at
242              
243             L
244              
245             For other issues, or commercial enhancement or support, contact the author.
246              
247             =head1 AUTHORS
248              
249             Adam Kennedy Eadamk@cpan.orgE, Ron Savage Ersavage@cpan.orgE
250              
251             =head1 ACKNOWLEGEMENTS
252              
253             This module is 99% as per L by Adam Kennedy.
254              
255             Ron Savage made some tiny changes to suppport the preservation of key order.
256              
257             The test suite was likewise adapted.
258              
259             =head1 SEE ALSO
260              
261             L, L, L, L, L
262              
263             =head1 Copyright
264              
265             Copyright 2002 - 2008 Adam Kennedy.
266              
267             Australian copyright (c) 2009, Ron Savage.
268             All Programs of Ron's are 'OSI Certified Open Source Software';
269             you can redistribute them and/or modify them under the terms of
270             the Artistic or the GPL licences, copies of which is available at:
271             http://www.opensource.org/licenses/index.html
272              
273             =cut