Well, I see your point. What if we add a parameter which controls such a
feature? I added such an option (using the [] scheme). Check out the
attached patch (to 2.46).
diff -rc Config-General-2.46/Changelog Config-General-2.47/Changelog
*** Config-General-2.46/Changelog Thu Apr 8 11:24:22 2010
--- Config-General-2.47/Changelog Thu Apr 8 12:28:34 2010
***************
*** 1,3 ****
--- 1,8 ----
+ 2.47
+ - fixed rt.cpan.org#53759 by adding new option -ForceArray.
+ when enabled a single config value enclosed in [] will become
+ an array forcefully.
+
2.46
- fixed rt.cpan.org#56370: there was a sort() call in _store()
left, which lead to sorted arrays even if -SaveSorted were
diff -rc Config-General-2.46/General.pm Config-General-2.47/General.pm
*** Config-General-2.46/General.pm Thu Apr 8 11:20:51 2010
--- Config-General-2.47/General.pm Thu Apr 8 12:23:52 2010
***************
*** 32,38 ****
use Carp;
use Exporter;
! $Config::General::VERSION = 2.46;
use vars qw(@ISA @EXPORT_OK);
use base qw(Exporter);
--- 32,38 ----
use Carp;
use Exporter;
! $Config::General::VERSION = 2.47;
use vars qw(@ISA @EXPORT_OK);
use base qw(Exporter);
***************
*** 86,92 ****
parsed => 0, # internal state stuff for variable interpolation
files => {}, # which files we have read, if any
UTF8 => 0,
! SaveSorted => 0
};
# create the class instance
--- 86,93 ----
parsed => 0, # internal state stuff for variable interpolation
files => {}, # which files we have read, if any
UTF8 => 0,
! SaveSorted => 0,
! ForceArray => 0 # force single value array if value enclosed in []
};
# create the class instance
***************
*** 864,876 ****
}
}
else {
! # standard config option, insert key/value pair into node
! $config->{$option} = $this->_parse_value($config, $option, $value);
! if ($this->{InterPolateVars}) {
! # save pair on local stack
! $config->{__stack}->{$option} = $config->{$option};
! }
}
}
}
--- 865,883 ----
}
}
else {
! if($this->{ForceArray} && $value =~ /^\[\s*(.+?)\s*\]$/) {
! # force single value array entry
! push @{$config->{$option}}, $this->_parse_value($config, $option, $1);
! }
! else {
! # standard config option, insert key/value pair into node
! $config->{$option} = $this->_parse_value($config, $option, $value);
! if ($this->{InterPolateVars}) {
! # save pair on local stack
! $config->{__stack}->{$option} = $config->{$option};
! }
! }
}
}
}
***************
*** 1201,1212 ****
foreach my $entry ( $this->{SaveSorted} ? sort keys %$config : keys %$config ) {
if (ref($config->{$entry}) eq 'ARRAY') {
! foreach my $line ( $this->{SaveSorted} ? sort @{$config->{$entry}} : @{$config->{$entry}} ) {
! if (ref($line) eq 'HASH') {
! $config_string .= $this->_write_hash($level, $entry, $line);
! }
! else {
! $config_string .= $this->_write_scalar($level, $entry, $line);
}
}
}
--- 1208,1225 ----
foreach my $entry ( $this->{SaveSorted} ? sort keys %$config : keys %$config ) {
if (ref($config->{$entry}) eq 'ARRAY') {
! if( $this->{ForceArray} && scalar @{$config->{$entry}} == 1 && ! ref($config->{$entry}->[0]) ) {
! # a single value array forced to stay as array
! $config_string .= $this->_write_scalar($level, $entry, '[' . $config->{$entry}->[0] . ']');
! }
! else {
! foreach my $line ( $this->{SaveSorted} ? sort @{$config->{$entry}} : @{$config->{$entry}} ) {
! if (ref($line) eq 'HASH') {
! $config_string .= $this->_write_hash($level, $entry, $line);
! }
! else {
! $config_string .= $this->_write_scalar($level, $entry, $line);
! }
}
}
}
***************
*** 2154,2160 ****
! =head1 IDENTICAL OPTIONS
You may have more than one line of the same option with different values.
--- 2167,2173 ----
! =head1 IDENTICAL OPTIONS (ARRAYS)
You may have more than one line of the same option with different values.
***************
*** 2229,2235 ****
--- 2242,2257 ----
If turned off, Config::General will complain about multiple occurring options
with identical names!
+ =head2 FORCE SINGLE VALUE ARRAYS
+
+ You may also force a single config line to get parsed into an array by
+ turning on the option B<-ForceArray> on and by surrounding the value of the
+ config entry by []. Example:
+
+ hostlist = [ foo.bar ]
+ Will be a singlevalue array entry if the option is turned on. If you want
+ it to remain to be an array you have to turn on B<-ForceArray> suring save too.
=head1 LONG LINES
***************
*** 2510,2516 ****
=head1 VERSION
! 2.46
=cut
--- 2532,2538 ----
=head1 VERSION
! 2.47
=cut
diff -rc Config-General-2.46/t/run.t Config-General-2.47/t/run.t
*** Config-General-2.46/t/run.t Thu Apr 8 11:23:14 2010
--- Config-General-2.47/t/run.t Thu Apr 8 12:27:19 2010
***************
*** 8,14 ****
use Data::Dumper;
! use Test::More tests => 61;
#use Test::More qw(no_plan);
# ahem, we deliver the test code with a local copy of
--- 8,14 ----
use Data::Dumper;
! use Test::More tests => 63;
#use Test::More qw(no_plan);
# ahem, we deliver the test code with a local copy of
***************
*** 702,704 ****
--- 702,715 ----
$cfg51 = new Config::General( -ConfigFile => "t/cfg.51.out", -InterPolateVars => 1 );
my %hash51new = $cfg51->getall();
is_deeply(\%hash51, \%hash51new, "compare saved config containing escaped chars");
+
+
+ # check if forced single value arrays remain
+ my $cfg52 = new Config::General( -String => "habeas = [ corpus ]", -ForceArray => 1);
+ my %hash52 = $cfg52->getall();
+ my @array52 = qw(corpus);
+ is_deeply($hash52{habeas}, \@array52, "check -ForceArray single value arrays");
+ $cfg52->save_file("t/cfg.52.out");
+ $cfg52 = new Config::General( -ConfigFile => "t/cfg.52.out", -ForceArray => 1);
+ my %hash52new = $cfg52->getall();
+ is_deeply(\%hash52new, \%hash52, "check -ForceArray single value arrays during save()");