in reply to Re^4: Config files
in thread Config files

Just choose a delimiter and split the values after you read them. What delimiter to use depends on the characters allowed in the values, but most of the time comma is good enough. So assuming the INI contains:

[path] files=foo.txt,bar.txt,baz.csv
you'd just need to do something like:
@files = split /\s*,\s*/, $config->{path}{files}; # the \s* removes the optional whitespace around delimiters
You might do the splitting inside the forValue=> callback, but I think that would just complicate the code. You'd have to specify what values to split, because you'd definitely not want to split everything that contains the delimiter. So I think it's better to split after everything is read.

If you did want to modify the $config structure to contain certain values as arrays you might do something like this:

foreach my $Section (values %$config) { # $Section is a hash ref containing the values of the section, not th +e section name! foreach my $value (qw(files colors and other options that should be +arrays)) { $Section->{$value} = [split /\s*,\s*/, $Section->{$value}]; } }
After this the $config->{anySection}{files} is no longer a string but a reference to an anonymous array containing the individual items.

Jenda
We'd like to help you learn to help yourself
Look around you, all you see are sympathetic eyes
Stroll around the grounds until you feel at home
   -- P. Simon in Mrs. Robinson

Replies are listed 'Best First'.
Re^6: Config files
by sparkel (Acolyte) on Dec 11, 2004 at 00:54 UTC
    Hi Jenda

    Thank you for the reply. I understood:

    @files = split /\s*,\s*/, $config->{path}{files};

    If the arrays can occur at any place in the config file along with scalar values, I did not understand how the following code takes care of that

    foreach my $Section (values %$config) { # $Section is a hash ref containing the values of the section, not th +e section name! foreach my $value (qw(files colors and other options that should be +arrays)) { $Section->{$value} = [split /\s*,\s*/, $Section->{$value}]; } }

    Actually, I did not understand the following line:

    foreach my $value (qw(files colors and other options that should be +arrays)) {

    Thanks.

      qw(foo bar baz) means the same as ('foo', 'bar', 'baz'). The inner loop loops through the names of the options that you want to split.

      The thing is that if you split everything that contains the delimiters you run into problems. You'd have to check all the time whether $config->{sectionName}{valueName} is a scalar or an array ref. That'd be inconvenient. So it's better to split the options that may contain multiple values (even if they don't in some case) and leave the others intact. So that you can be sure $config->{path}{root} is a string and $config->{path}{files} is an array (ref).

      Jenda
      We'd like to help you learn to help yourself
      Look around you, all you see are sympathetic eyes
      Stroll around the grounds until you feel at home
         -- P. Simon in Mrs. Robinson

        Hi Jenda,

        Thanks for the response. Does that mean I need to hardcode the names of arrays that will be written in the config file to put them in the "qw()" ?

        So, if my config file contains:

        [one] size = 1,2,3,4 root = C:\test [two] colors = red,blue,green code = %root%\code1

        Then, having:

        use Config::IniHash qw(ReadINI); use Data::Dumper; $config = ReadINI('testiINI.ini', systemvars => 0, forValue => sub { my ($name, $value, $sectionname, $INIhashref) = @_; next if /^(#.*)?$/; $value =~ s{%(?:\[([^\]%]+)\])?([^%]*)%}{ print "for value: $value this is 1: $1 this is 2: $2 \n\n" +; if ($2 eq '') { '%' } elsif ($1 eq '') { $INIhashref->{$sectionname}{$2} } else { $INIhashref->{$1}{$2} } }ge; return $value; } ); foreach my $Section (values %$config) { foreach my $value ( qw( colors size ) ) { $Section->{$value} = [split /\s*,\s*/, $Section->{$value}]; } }

        I am not sure if that is what you meant...but I am not too sure what you said should go into the qw(). How does the code determine what is the scalar variable and what is an array? Thank you.