Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Matts (1087)

Matts
  (email not shown publicly)

I work for MessageLabs [messagelabs.com] in Toronto, ON, Canada. I write spam filters, MTA software, high performance network software, string matching algorithms, and other cool stuff mostly in Perl and C.

Journal of Matts (1087)

Friday May 02, 2008
01:59 PM

Config file complication

[ #36318 ]

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.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • 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: [cpan.org]
  • 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 '@' prefi

    • 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.
      --

      @JAPH = qw(Hacker Perl Another Just);
      print reverse @JAPH;
    • 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".
  • ... is probably marginally better than cutting and pasting that 50 lines.

    Or alternatively, cut and past Config::Tiny into your code as Module::Config.
    • Yup. The point being that configuration data is pretty simple and you shouldn't over complicate it unless you have really crazy needs.
      • 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).
        • 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//;

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