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

Hello! I'm quite new at Perl and trying to build a config file written in perl and then pull it into a main file to setup variables. I've read the tutorials but still fail to grasp the concept. What am I doing wrong and how should I do it? I've been at it for 1.5 day now. Code is shortened since the config file is rather large but the concept is the same.

#!/usr/bin/perl -w use strict; use warnings; my $MATCH_FILE="/path/to/patterns.pl"; my @LOGE; # this is an array that should be "configured" by the patter +n.pl my $return; unless ($return = do $MATCH_FILE) { warn "couldn't parse $MATCH_FILE: $@" if $@; warn "couldn't do $MATCH_FILE: $!" unless defined $retu +rn; warn "couldn't run $MATCH_FILE" unless $return; } print $return; # this prints 2 printLogPatterns(@LOGE);

In this file I want to set the @LOGE file to a variable set in the patterns.pl file.

#pattern.pl use strict; use warnings; my $astring = "This is an example string"; # not accessed @LOGE = ( { HASH => "a hash"},{ HASH => "Another one"} ); # this is wh +at I want to be "exported" sub asub{ print "a sub"; }# is this also possible to "export"?

I'd like to use a pulled in perl config file since it would be good to configure the application quite fast and the possibilities looked very promising. Any help is appreciated

Replies are listed 'Best First'.
Re: Making use of a config file written in Perl
by eyepopslikeamosquito (Archbishop) on Oct 25, 2010 at 21:04 UTC
Re: Making use of a config file written in Perl
by Anonymous Monk on Oct 25, 2010 at 21:07 UTC
    If you actually did have use strict in the included file patterns.pl, you'd have gotten

    couldn't parse .../patterns.pl: Global symbol "@LOGE" requires explici +t package name at ...

    This is because do does not see lexicals in the enclosing scope, i.e. your my @LOGE, which I suppose was the idea. Rather, the @LOGE in patterns.pl is treated as a separate package variable.

    You could use string eval instead (which does see lexicals in the enclosing scope). I.e., read the contents of patterns.pl into a string and eval it

    my $config; { local $/ = undef; open my $fh, "<", $MATCH_FILE or die $!; $config = <$fh>; } my $return; unless ($return = eval $config) {

    Alternatively (and usually better), create a proper module and use Exporter.

Re: Making use of a config file written in Perl
by Marshall (Canon) on Oct 25, 2010 at 23:20 UTC
    it would be good to configure the application quite fast
    You may be trying to optimize something on the basis of some perceived speed gain that is just not there or which makes no difference. Unless you have some really special requirement, anything that you do is going to be just fine speed wise.

    I don't really understand enough from your description of what you are trying to configure, but you may find that some standard modules will suit your purpose quite well. I would not put code into a file that a user is going to edit!

    For something that a user might muck with, I find the series of Config* modules to be quite nice. They implement a HoH or HoHoH structure which can be accessed easily. Although sometimes I put my own module as a thin "wrapper" around that so that I wind up with something that just looks like a rocket fast DB. So instead of having a predefined variable in my code, I call my @filehistory = getdb('filehistory') or whatever when I need it.

    I do have modules that init themselves by reading complicated hereis documents or other structures. That is fine too. For example one table I have has changed once in the last 20 years(existed before current Perl code) - and required coding changes to deal with the ramifications. Its just fine to put something like that in a program module that only somebody on the programming team should be messing with!

    I have other modules that read in thousands of lines of data information and present a simple I/F to the rest of the code - but this isn't in the range of what I could call "configuration" - this is operational data.

    Sorry to be long winded. But, either make a module that is part of "your" code and you "own" or make some sort of file (Config style or YAML, etc) that contains no code at all. Avoid putting your code into some user modifiable file.

Re: Making use of a config file written in Perl
by locked_user sundialsvc4 (Abbot) on Oct 25, 2010 at 22:29 UTC

    If you are going to put settings into a Perl module, be sure that this module includes use strict and use warnings, and that it is either used or required by “the main settings-handling module” of your application.

    “Incorrect or incomplete settings” are a very troublesome source of application problems for many end-users, and the time you spend aggressively checking them for omissions and inconsistencies (producing meaningful messages to describe each case) will be well worth the time.

Re: Making use of a config file written in Perl
by aquarium (Curate) on Oct 25, 2010 at 23:06 UTC
    i either use the config module (if i need sections within config) or just use a plain txt file that has a variable then pipe character then value, per line. a short routine reads in the config variables as hash key and value pairs into %config hash, which override any previously defined (hardcoded) defaults. keeps the config neatly separate from any other variables, and you can clearly see where you do make use of config vars. i can't take the credit for this, as that's the way a large piece of software i worked on did.
    the hardest line to type correctly is: stty erase ^H