Config file complication

Matts on 2008-05-02T18:59:51

Someone asked on IRC today what's a nice simple module to use for config files. Someone suggest YAML. Jeez, talk about not simple. And YAML is actually hard to write by hand. Someone else suggested XML with XML::Simple. Same thing - a large complex module and the config format isn't particularly user editable. No disrespect meant to those who suggested those things - I just think differently...

All you usually need is INI files. Here's a simple parser I often use:

sub parse_config {
    my ($self, $file) = @_;
    open(my $fh, $file) || die "open($file): $!";
    my @lines = <$fh>;
    close $fh;
    chomp(@lines);
    my $config = $self->{config} = {};
    my $section;
    for (@lines) {
        s/^\s*//;
        s/\s*$//;
        next unless /\S/;
        next if /^#/;
        if (/^ \[ (.*) \] $/x) {
            $section = $config->{uc$1} = {};
        }
        elsif (/^ (\w+) \s* = \s* (.*) $/x) {
            die "key=value pair outside of a section" unless $section;
            $section->{lc$1} = $2;
        }
        else {
            die "invalid line in $file: $_";
        }
    }
}
It's nice and simple, requires no external modules or CPAN downloads, and works pretty well for most situations where simple config files are needed.


So many to choose from

grink on 2008-05-03T00:06:26

The great thing about Config:: is that there are so many to choose from...

I've come to like using Catalyst::Plugin::ConfigLoader as a straightforward way of getting a text config into a hash.

C::P::CL is built on top of the excellent Config::Any, so you can use .ini, .yaml, .conf (Config::General), .json, and even .pl (maybe more?)
Unfortunately, C::P::CL is built into Catalyst, so I (plug) wrote a factored out version called Config::JFDI

If you're not afraid of a few dependencies, then you should give Config::JFDI a look!

I tend to agree

grantm on 2008-05-03T02:32:18

In my experience, YAML is a read-only format. It's probably just that I haven't used it enough but every time I try to hand craft YAML I get bitten by the subtleties.

I had a brief flirtation with XML and a config file format some years ago and I still paying the price :-)

I've used hand-rolled parser code for ini-style configs a number of times recently. I haven't bothered with implementing [sections] but often need to include multi-value items. The way I tend to handle that is by putting an '@' prefix on the key name in the ini file - causing it to be parsed into an array.

Re:I tend to agree

TeeJay on 2008-05-17T09:10:15

Sounds like reinventing the wheel to me : Config::Tiny and Config::Simple (look no dependancies (http://cpandeps.cantrell.org.uk/?module=config%3A%3Asimple&perl=any+version&os= any+OS) are both simple, small and deal with most edge cases so you don't have to.

My favorite configuration format is

btilly on 2008-05-03T03:25:25

Perl!

Re:My favorite configuration format is

markjugg on 2008-05-04T01:12:08

Mine is as well. I like the simplicity and flexibility, and my reality is that the config files are edited by programmers, so the Perl syntax is not "scary".

Config::Tiny

Alias on 2008-05-04T04:35:42

... is probably marginally better than cutting and pasting that 50 lines.

Or alternatively, cut and past Config::Tiny into your code as Module::Config.

Re:Config::Tiny

Matts on 2008-05-04T14:44:36

Yup. The point being that configuration data is pretty simple and you shouldn't over complicate it unless you have really crazy needs.

Re:Config::Tiny

Ron Savage on 2008-05-04T23:27:29

What the point of the *s in:
s/^\s*//;
s/\s*$//;
Surely you never want to match 0 spaces, so why not use s+? (That's an English ?, not a Perl one).

Re:Config::Tiny

Alias on 2008-05-19T03:37:10

Hrm... I'm not sure there is a point, could just be a legacy of some old code that did something like

s/^\s*something//;

Re:Config::Tiny

Matts on 2008-05-19T14:06:19

Just habit. Everywhere I've ever seen whitespace removed it's used \s* rather than \s+. Perhaps historically \s* matched faster?