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

You don't have to hardcode the names if you do not want to, but it's IMHO the best solution. There are basicaly three possible solutions.

  1. you can use the code above and specify what options allow multiple values. This way you know for sure that $config->{one}{root} is a string and $config->{one}{size} is an array. Which means you can safely write $path = $config->{one}{root} . "/processing.log"; and foreach my $size (@{$config->{one}{size}}) { ....
  2. You can split the values that contain the delimiters. This would allow the users to specify multiple values for any option in the INI file, the problem is that your script would have to be able to accept that. Otherwise you end up with $path (from the example in the previous solution) containing something like "ARRAY(0x14234234)/processing.log" which doesn't look too usefull to me. The same problem, just in the other direction would be with the "size" option, if the user did not specify several, the $config->{one}{size} would not be an array ref, but a string, so the foreach from the first solution would error out. I think this solution would complicate your script imensely.
  3. The last solution would be to split everything. Which means that $config->{sectionName}{optionName} would always be an array ref. And then if you had a use for just one value of an option you'd use $config->{sectionName}{optionName}[0] and if you wanted to do something with all of them you'd loop over @{$config->{sectionName}{optionName}}. The catch of this solution is that you might need to allow the delimiter in the value of some options. Or you would want to use a different delimiter for some options. Comma is fine if you are writing a list of color names, but is it so great for prices? What if the user enters prices=1,050? Did he/she mean two values, one and fifty or just one value, one thousand fifty?

You can choose whichever solution you like best, but my choice would be 1) any day.

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^10: Config files
by sparkel (Acolyte) on Dec 11, 2004 at 23:52 UTC
    Hi Jenda,

    Thanks for the suggestion. I think other than option 1, as you have suggested, other options would complicate a lot of things...and hence I'll specify the options that allow multiple values.

    If the config file contains:

    [path] root = C:\test code = %root%\code1 [array] files = hello.txt,hi.txt,howdy.txt dirs = %code%, %root%, %code%

    Then, for the "dirs" array, how can I change the following regular expression to find and store all values between %%..since there can be more than one (as seen in the dirs array)...

    $value =~ s{%(?:\[([^\]%]+)\])?([^%]*)%}{ if ($2 eq '') { '%' } elsif ($1 eq '') { $INIhashref->{$sectionname}{$2} } else { $INIhashref->{$1}{$2} } }ge;

      It already does, thanks to the /g option.

      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,

        It only works if the section name is added on. So,

        [path] root = C:\test [path2] m = C:\path2 root = C:\code [check] #this will work p = %[path]root%, %[path2]m% [check2] #this will not work...even though m is only entered once q = %[path]root%, %m%

        Please tell me how I can change the code to recognize the correct variable when the path is not mentioned...since m is seen only once in the config file...it should be able to recongnize it...but it does not seem to. Thank you.