CPANPLUS-YACSmoke
view release on metacpan or search on metacpan
lib/CPANPLUS/YACSmoke/IniFiles.pm view on Meta::CPAN
# Description: Returns the first key in the hash
# ----------------------------------------------------------
# Date Modification Author
# ----------------------------------------------------------
# ----------------------------------------------------------
sub FIRSTKEY {
my $self = shift;
$self->{tied_enumerator}=0;
return $self->NEXTKEY();
} # end FIRSTKEY
# ----------------------------------------------------------
# Sub: Config::IniFiles::_section::NEXTKEY
#
# Args: $last
# $last The last key accessed by the interator
#
# Description: Returns the next key in line
# ----------------------------------------------------------
# Date Modification Author
# ----------------------------------------------------------
# ----------------------------------------------------------
sub NEXTKEY {
my $self = shift;
my( $last ) = @_;
my $i=$self->{tied_enumerator}++;
my @keys = $self->{config}->Parameters($self->{section});
my $key=$keys[$i];
return if (! defined $key);
return wantarray ? ($key, $self->FETCH($key)) : $key;
} # end NEXTKEY
# ----------------------------------------------------------
# Sub: Config::IniFiles::_section::DESTROY
#
# Args: (None)
#
# Description: Called on cleanup
# ----------------------------------------------------------
# Date Modification Author
# ----------------------------------------------------------
# ----------------------------------------------------------
sub DESTROY {
# my $self = shift
} # end DESTROY
1;
=head1 IMPORT / DELTA FEATURES
The I<-import> option to L</new> allows one to stack one
I<Config::IniFiles> object on top of another (which might be itself
stacked in turn and so on recursively, but this is beyond the
point). The effect, as briefly explained in L</new>, is that the
fields appearing in the composite object will be a superposition of
those coming from the ``original'' one and the lines coming from the
file, the latter taking precedence. For example, let's say that
C<$master> and C<overlay> were created like this:
my $master = Config::IniFiles->new(-file => "master.ini");
my $overlay = Config::IniFiles->new(-file => "overlay.ini",
-import => $master);
If the contents of C<master.ini> and C<overlay.ini> are respectively
; master.ini
[section1]
arg0=unchanged from master.ini
arg1=val1
[section2]
arg2=val2
and
; overlay.ini
[section1]
arg1=overriden
Then C<< $overlay->val("section1", "arg1") >> is "overriden", while
C<< $overlay->val("section1", "arg0") >> is "unchanged from
master.ini".
This feature may be used to ship a ``global defaults'' configuration
file for a Perl application, that can be overridden piecewise by a
much shorter, per-site configuration file. Assuming UNIX-style path
names, this would be done like this:
my $defaultconfig = Config::IniFiles->new
(-file => "/usr/share/myapp/myapp.ini.default");
my $config = Config::IniFiles->new
(-file => "/etc/myapp.ini", -import => $defaultconfig);
# Now use $config and forget about $defaultconfig in the rest of
# the program
Starting with version 2.39, I<Config::IniFiles> also provides features
to keep the importing / per-site configuration file small, by only
saving those options that were modified by the running program. That
is, if one calls
$overlay->setval("section1", "arg1", "anotherval");
$overlay->newval("section3", "arg3", "val3");
$overlay->WriteConfig(-delta=>1);
C<overlay.ini> would now contain
; overlay.ini
[section1]
arg1=anotherval
[section3]
arg3=val3
This is called a I<delta file> (see L</WriteConfig>). The untouched
[section2] and arg0 do not appear, and the config file is therefore
shorter; while of course, reloading the configuration into C<$master>
and C<$overlay>, either through C<< $overlay->ReadConfig() >> or through
the same code as above (e.g. when application restarts), would yield
exactly the same result had the overlay object been saved in whole to
the file system.
The only problem with this delta technique is one cannot delete the
default values in the overlay configuration file, only change
them. This is solved by a file format extension, enabled by the
I<-negativedeltas> option to L</new>: if, say, one would delete
parameters like this,
$overlay->DeleteSection("section2");
$overlay->delval("section1", "arg0");
$overlay->WriteConfig(-delta=>1);
The I<overlay.ini> file would now read:
; overlay.ini
[section1]
; arg0 is deleted
arg1=anotherval
; [section2] is deleted
[section3]
arg3=val3
Assuming C<$overlay> was later re-read with C<< -negativedeltas => 1 >>,
the parser would interpret the deletion comments to yield the correct
result, that is, [section2] and arg0 would cease to exist in the
C<$overlay> object.
=cut
=head1 DIAGNOSTICS
=head2 @Config::IniFiles::errors
Contains a list of errors encountered while parsing the configuration
file. If the I<new> method returns B<undef>, check the value of this
to find out what's wrong. This value is reset each time a config file
is read.
=head1 BUGS
=over 3
=item *
The output from [Re]WriteConfig/OutputConfig might not be as pretty as
it can be. Comments are tied to whatever was immediately below them.
And case is not preserved for Section and Parameter names if the -nocase
option was used.
=item *
No locking is done by [Re]WriteConfig. When writing servers, take
care that only the parent ever calls this, and consider making your
own backup.
=back
=head1 Data Structure
Note that this is only a reference for the package maintainers - one of the
upcoming revisions to this package will include a total clean up of the
data structure.
$iniconf->{cf} = "config_file_name"
->{startup_settings} = \%orginal_object_parameters
->{firstload} = 0 OR 1
->{imported} = $object WHERE $object->isa("Config::IniFiles")
->{nocase} = 0
->{reloadwarn} = 0
->{sects} = \@sections
->{mysects} = \@sections
->{sCMT}{$sect} = \@comment_lines
->{group}{$group} = \@group_members
->{parms}{$sect} = \@section_parms
->{myparms}{$sect} = \@section_parms
->{EOT}{$sect}{$parm} = "end of text string"
->{pCMT}{$sect}{$parm} = \@comment_lines
->{v}{$sect}{$parm} = $value OR \@values
=head1 AUTHOR and ACKNOWLEDGEMENTS
The original code was written by Scott Hutton.
Then handled for a time by Rich Bowen (thanks!),
It is now managed by Jeremy Wadsack,
with many contributions from various other people.
( run in 0.609 second using v1.01-cache-2.11-cpan-140bd7fdf52 )