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

Memorable Monks,

Putting my configuration variables into a separate config file and then 'requiring' it. Finding that if the last variable declaration sets a variable to zero, I get the error message:

"Error - config.pl did not return a true value"

But if I ensure that the last declaration sets a variable to something, anything but zero, it works just fine.

This seems like strange behaviour to me. What's up?

Main file:

#!/usr/bin/perl -w require 'config.pl'; print "Content-type:text/html\n\n"; print $variable;
config.pl
$v1 = 'something'; ..... $variable = 'hello world'; $flag = 0;
This config.pl produces the error.

$v1 = 'something'; ..... $variable = 'hello world'; $flag = 1;
This config.pl works just fine.

It's not the value ofthe flag in the program - the program doesn't even run. It stops on loading because of this error.




Forget that fear of gravity,
Get a little savagery in your life.

Replies are listed 'Best First'.
Re: 'Required' config file produces error if last entry sets variable to zero?
by Zaxo (Archbishop) on Jun 11, 2006 at 14:24 UTC

    A file which is required or used must end with a true value. Just make

    1;
    the last line of the config file.

    It doesn't seem well-known, but return will stop execution of a loaded file, making return 0; a way to cancel loading and return 1; a way to say "You don't need the rest of this."

    (Added) To keep strict happy, you should add,

    use vars qw/$v1 ..... $variable $flag/;
    to the top of the file. Tacking on my won't work, since lexical variables only have file scope, at most, and can't be seen from the require-ing program.

    After Compline,
    Zaxo

      Thanks - that's exactly what I did to make it work, but I thought it was a hack.




      Forget that fear of gravity,
      Get a little savagery in your life.
Re: 'Required' config file produces error if last entry sets variable to zero?
by rblasch (Monk) on Jun 11, 2006 at 16:12 UTC
    Consider using do 'config.pl'; instead. That way you don't need to return a true value.
      There's a few pitfalls with do:
      • do doesn't do the error checking that require does regardling the loading of a file (you need to check the return value)
      • do forces a load/execute of the file, even if it's already loaded (require doesn't load/execute files more than once)

      See do in the documentation (do EXPR is what you're interested in).

        Whether those pitfalls are a good or a bad thing probably depends on the requirements. For example, if one would like to support config reloading the second pitfall would actually be a good thing.

        I guess the issue is more a matter of style than any technical reason. It might be best to choose whatever one feels comfortable with.

        It may even depend on how you view the configuration: If the configuration feels like part of the program, require or use might be better because it's heaviliy associated with module loading. That way, the final 1; in the configuration won't feel awkward, too. If the configuration is more external, and Perl is mostly used for syntactic convenience, I'd prefer do.

Re: 'Required' config file produces error if last entry sets variable to zero?
by Anonymous Monk on Jun 12, 2006 at 09:07 UTC
    the config.pl program is like a module you are using and it always require a <truevalue>; to imply that module is completed.
Re: 'Required' config file produces error if last entry sets variable to zero?
by CountZero (Bishop) on Jun 12, 2006 at 16:17 UTC
    Did you ever consider using something like YAML or Config::INI::Simple for your configuration file?

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: 'Required' config file produces error if last entry sets variable to zero?
by qazwart (Scribe) on Jun 13, 2006 at 16:47 UTC
    Me don't like...

    The problem with what you're doing is that you can have someone write dangerous code in their config file which you'd just interpret on your merry way. It's sort of like setting up a Perl CGI script that takes input and does a system call on it.

    Besides, Perl code is not exactly easy for a novice to figure out. Even if it's just <var> = <value> lines. Did they put a "$" is front of each variable? What about semicolons on the end of each line? Plus, if you used "use strict", they'd have to put "my" infront of each variable. Better to read in the config file and parse it yourself. Even if all you're doing is an eval on the line. At least you can check each line's grammar to make sure the user is only setting a variable. Something like this:

    open(CONFIG, "$file") or die qq(Can't open "$file" for reading); foreach $line (<CONFIG>) { eval qq($line) or die qq("$line" is not valid code!); }
    I think you're better off using Config::INI::Simple. It makes a nicer and easier to understand Config file.