leocharre has asked for the wisdom of the Perl Monks concerning the following question:

i got a neat question..

i'm reading a conf file, splitting it up into key val pairs ti put into a hash. this sub is some'pin like..

sub conf2hash { my %argv = @_; =pod usage: conf2hash( file=>'path/2/file', hashref=> \%yourhash, splitchar=>' +=', commentchar=> '#'); if splitchar is null, default is = sign if commentchar is null, default is # mark # one key val pair per line # returns 0 on errors =cut defined $argv{splitchar} or $argv{splitchar}='='; defined $argv{hashref} or return 0; defined $argv{commentchar} or $argv{commentchar}='#'; defined $argv{file} or return 0; open (IN, "< $argv{file}") or die($!); while (<IN>) { if ( $_=~m/^$argv{commentchar}|^\s+$/ ) { next;} $_=~s/\s//g; my @a = split(/$argv{splitchar}/,$_); ${$argv{hashref}}{$a[0]}=$a[1]; } close IN; return 1; }
An example conf file...
THIS=that name=joe height=heyman #this is a comment age=14

Here's my question... where i read in the line and then split it..

my @a = split(/$argv{splitchar}/,$_); #and then, place it into the hash.... ${$argv{hashref}}{$a[0]}=$a[1];

isn't there some other way to do this like...

split(/$argv{splitchar}/,$_); ${$argv{hashref}}{$_[0]}=$_[1]; # is that ok ?? # and what about some thing like.. # (and I DONT KNOW the syntax, that's why im here!!) ( ${$argv{hashref}}{$_} = $_ )= split(/$argv{splitchar}/,$_); #is that totally making it up ?

any code shortcuts ?:)

Replies are listed 'Best First'.
Re: split line and populate hash shortcut ?
by BrowserUk (Patriarch) on Feb 14, 2006 at 17:31 UTC

    Rather than split, use a regex to extract the key and value and also skip any non-matching lines.

    #! perl -slw use strict; use Data::Dumper; my %config; m[^([^#][^=]+)=(.*)$] and $config{ $1 } = $2 while <DATA>; print Dumper \%config; __DATA__ THIS=that name=joe height=heyman #this is a comment age=14

    You might want to expand that a little and incorporate warnings about non-matching, non-blank, non-comment lines?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Or
      m[^([^#][^=]+)=([^#\n]*)] and $config{ $1 } = $2 while <DATA>;
      To allow end of line comments and remove newlines from the "value" part. Removing trailing spaces is left as an exercise to the reader :-)
      my %config; m[^([^#][^=]+)=(.*)$] and $config{ $1 } = $2 while <DATA>;
      You could even write this as:
      my %config = map { /^([^#][^=]+)=(.*)$/ } <DATA>;
      There is an example somewhere in the perldocs that gives essentially the same technique for parsing simple config files, though I can't find it right now. I always thought it was ingenius & wonderfully succinct. It certainly applies nicely here.

      blokhead

      ooohh... i like i like... obviously the right thing to do! :) Thank you!
Re: split line and populate hash shortcut ?
by salva (Canon) on Feb 14, 2006 at 17:25 UTC
    my $cfg = Config::Properties::Simple->new(file => $fn); my %props = $cfg->properties;

    CPAN is your friend!

      CPAN is your friend!

      Out of interest, could you explain why you chose that particular module from the 150+ Config* modules in this case?


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        oh, just because I am maintaining it so I know it, and because it parses property files that reassemble more or less the requirements of the original poster!
Re: split line and populate hash shortcut ?
by Praveen (Friar) on Feb 20, 2006 at 15:36 UTC
    Try This
    while(<DATA>) { unless((/^\s$/) | (/^#/)) { $config{$`}=$',if(/=/); } }
Re: split line and populate hash shortcut ?
by revdiablo (Prior) on Feb 15, 2006 at 17:16 UTC

    Another possible solution, sticking with split but using map:

    my %config = map { chomp; /^#/ ? () : split /=/, $_, 2 } <IN>;