package NYSDOT::Config::IniFiles; use strict; use warnings; use Config::IniFiles; use Time::Format qw/time_format/; our @ISA = ("Config::IniFiles"); our $VERSION = "0.3"; =head1 NYSDOT::Config::IniFiles A thin wrapper around the OO interface of C. =head1 VERSION 0.3 =head1 COPYRIGHT NYSDOT, 2003 =head1 AUTHOR Will Coleda (LTI) =head1 METHODS =head2 new This constuctor takes the same arguments at that for C. (a hash of -name and value pairs). If an argument of C<-interpolate> (with a valid section name as a value) is passed into the constructor, then we look for a section with the same name as the value of that argument. If present, all parameters declared in that section are considered variables. Any occurances of that parameter name surrounded by %'s in a value (not in the paramater name itself) are interpolated with the value of that parameter. Additionally, if this section is present, parameters of the form C<%TIME=yyyymmdd%> will automatically be expanded. Anything after the C<=> will be passed to C. For example, C<%TIME=yymm%> will expand to C<0301> in January, 2003. See L for more details. A new instance of a Config::IniFiles object is created in which: these substitutions are made; the section that defined the interpolations is removed; the parameters passed to its constructor do not include C<-interpolate>. If the C<-interpolate> is not present in the original (or referred to an invalid section), then no substitutions are done. A warning is emitted in the case of an invalid section. =cut sub new { my $proto = shift; my %args = @_; my $class = ref($proto) || $proto; my $interpolate = 0; if ($args{"-interpolate"}) { $interpolate = $args{"-interpolate"}; } delete $args{"-interpolate"}; my $obj = $class->SUPER::new (%args); if ($interpolate) { if (! $obj->SectionExists($interpolate)) { warn "invalid interpolation section $interpolate specified"; } my %params; foreach my $param ($obj->Parameters($interpolate)) { $params{$param} = $obj->val($interpolate,$param); } $obj->DeleteSection($interpolate); foreach my $section ($obj->Sections()) { foreach my $param ($obj->Parameters($section)) { my $val = $obj->val($section,$param); # Explicit parameter substitution foreach my $param (keys %params) { $val =~ s/%$param%/$params{$param}/gi; } # Automatic TIME= substitution. $val =~ s/%TIME=([^%]+)%/time_format($1)/gei; $obj->newval($section,$param,$val); } } } # now, rebless into our own class. bless($obj,$class); } =head2 boolean Similar to C's C method. Takes an optional parameter to indicate the default if not specified. If the specified section and parameter don't exist, undef is returned, unless a default is supplied, it which case it is returned. If the value exists, and is one of C<0>, C, C, C, then the function returns true, otherwise false. (NB: the default value passed in, and the return value, are Perlian true/false values, and not Configian.) =cut sub boolean { my $self = shift; my ($section,$parameter,$default) = @_; defined($section) or die "Must specify section"; defined($parameter) or die "Must specify parameter"; my $val = $self->val($section,$parameter); if (defined($val)) { if ($val =~ /^\s*(0|FALSE|NO|OFF)\s*$/i) { return 0; } else { return 1; } } else { return $default; } } =head1 BUGS If you write the config back out to disk, it will overwrite the parameterized version, replacing it with a snapshot of the config as you were using it. This is not the right thing to do. So, don't do that. If you set an interpolated parameter to have a value that contains the name of another parameter surrounded by C<%>'s, multiple expansions may occur, depending on ordering. =cut 1;