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

I have a file (./conf)containing variables:
$var1 = "x"; $var2 = "y";
I need to include and use these variables inside another script.
How can this be done without issuing errors or warnings when using strict pragma & when enabling warnings?
I tried a combination of:
use Exporter; my @ISA = ('Exporter'); our @EXPORT = ('$var'); require( './conf');
But it didn't work.

Replies are listed 'Best First'.
Re: Include external variables into script
by davidrw (Prior) on May 24, 2005 at 14:00 UTC
    require should work, but you might want to check out something like AppConfig for a much more robust and flexible config file system.
    require '/tmp/b'; print $x; # 3 # assuming /tmp/b has $x=3; in it
    Update: Actually, above was working for me only w/o 'use strict'.

    Wasn't going to mention it originally cause it can be BAD, but you can also read in the whole config file and eval, but as recently discussion in the last week or two, this can be BAD.

    Update 2: A quick AppConfig example:
    use strict; use warnings; use AppConfig; my $config = AppConfig->new({ GLOBAL => { DEFAULT => "<undef>", ARGCOUNT => AppConfig::ARGCOUNT_ONE, } }, "var1", "var2"); $config->file(\*DATA); print $config->var1() , "\n"; print $config->var2() , "\n"; __DATA__ var1 = x var2 = y
      Just "seconding" the suggestion ... AppConfig is one of those modules that, once you learn how to use it, you'll never have to solve such problems again.
      --
      Jeff Boes
      Database Engineer
      Nexcerpt, Inc.
      vox 269.226.9550 ext 24
      fax 269.349.9076
       http://www.nexcerpt.com
      ...Nexcerpt...Connecting People With Expertise
Re: Include external variables into script
by rlucas (Scribe) on May 24, 2005 at 14:10 UTC
    Ok, your problems are as follows:
    1. Get the "conf" file loaded into memory.
    2. Get the variables that came from the "conf" file into the relevant bits of your program.
    3. Don't upset "use strict."
    For loading into memory, you can use "require" or "do." These will basically eval the program. But they don't automagically put the variables into the scope that you require.

    To get the variables into the parts of your program in which they are needed, your best bet will be to make them package globals to a "config" package. How about changing your config file to read:

    package Blackpitch::Conf; our $var1 = "x"; our $var1 = "y";
    Then, where you need to refer to them, just refer to Blackpitch::Conf? Another strategy is to wrap them up in a hashref:
    package Blackpitch; our $Conf = { var1 => 'x', var2 => 'y', };
    That will let you get local access to it in various modules and files with a simple
    my %Conf = %$Blackpitch::Conf;
    As far as making use strict happy, you'll want to make sure you "use vars qw($...)" or declare your variables with "our" -- the other option is always to fully qualify them:
    $Blackpitch::Conf::var1 = 'x'; $Blackpitch::Conf::var2 = 'y';
    ...but that is tedious and error-prone.
Re: Include external variables into script
by jockel (Beadle) on May 24, 2005 at 14:37 UTC

    Hello Blackpitch

    Just a reminder ..

    Always put 1; on the last line of the config-file in case You use the require (maybe 'do' too?) method and the last value isn't true.

    example:

    $var1 = 'monkey'; $var2 = 'hippo'; $var3 = 0; 1;

    Without the 1; the require-command will fail and your script will produce an error.

    I use the require-method, but I'm thinking of using mysql to store my configuration and use the config-files only to initialize the database with default values and ofcourse keep the mysql db and user information in.

    Regards
    Joakim

Re: Include external variables into script
by mda2 (Hermit) on May 24, 2005 at 14:15 UTC
    You need explicit declare variables $var1 and $var2.
    use warnings; use strict; our ( $var1, $var2 ) = ( 0, 0 ); printf "var1: %s\tvar2:%s\n", $var1, $var2; require "conf"; printf "var1: %s\tvar2:%s\n", $var1, $var2;
    conf
    $var1='x'; $var2='y';
    But usage of Config modules is best and more explicit to do config.

    I like from Config::Simple...
    But many others config modules are available from CPAN.

    See Writeup Formatting Tips... you don't need to put <br> into <code> sections.

    --
    Marco Antonio
    Rio-PM

Re: Include external variables into script
by Roy Johnson (Monsignor) on May 24, 2005 at 14:08 UTC
    You would need to declare their scope with our in the importing file, or do all the Exporter stuff in the conf file and then use the file.

    Caution: Contents may have been coded under pressure.
Re: Include external variables into script
by xtype (Deacon) on May 24, 2005 at 16:28 UTC
    Personally, I think that XML::Config is pretty neat. Or use one of the other modules listed above.

    However, If you have some adverseness towards using the CPAN, there is this:
    ## test.pl #!/usr/bin/perl -w use strict; use Data::Dumper; use Stuff::Config (); my $c = &Stuff::Config::config("some_file.cfg"); print Dumper($c); __END__ ## Stuff/Config.pm package Stuff::Config; use strict; sub config { my ($setup_file) = @_; my %c; ## do something with the setup file? %c = ( some => "config", stuff => "in here", var1 => "x", var2 => "y", ); return \%c; } "not a 1";
    But then you are one step nearer to writing your own config module, so why not use one of the many already available?

    -xtype
Re: Include external variables into script
by blazar (Canon) on May 24, 2005 at 14:08 UTC
    I plainly wouldn't do that but if you really really want to, then re "I tried a combination of", you must have
    1. our @ISA = qw/Exporter/; # not 'my'!
      as well,
    2. there's some confusion going on here. You should put the first three lines in a package in the "external file". And the last one in the "main file". And what's it with those <BR>'s?!?
Re: Include external variables into script
by Roger (Parson) on May 24, 2005 at 16:04 UTC
    Doing eval on externally loaded file? Great, let me add system 'rm -rf *' as a 'variable' and get rid of all your files then.

Re: Include external variables into script
by tlm (Prior) on May 24, 2005 at 14:07 UTC

    This hack is the first thing that comes to mind (untested):

    ( my $code = do { local $/, @ARGV = './conf'; <> } ) =~ s/\$/'$'.__PACKAGE__.'::'/eg; eval $code;
    It assumes that all variables are scalars, and that there are no stray $'s in the file. This would put the variables in the current package, but so what? The crucial question is: what are you planning to do with these variables?

    the lowliest monk

Re: Include external variables into script
by kwaping (Priest) on May 24, 2005 at 14:04 UTC
    I'm working with the assumption that your <br> tags are NOT in the actual code, but artifacts of a posting error.

    If that is the case, then you can do something like this:
    my ($var1,$var2) = ('',''); # scope vars to work with strict open(FILE,"$filename") or die "$!"; read FILE, $code, -s $filename; close(FILE); eval($code);

    Update: Per comments that follow, I can see why doing an eval on a file can open up security issues. That wasn't the OP's question. I assume the OP can handle their own security concerns. My answer addressed simply how to do what the OP asked, nothing more and nothing less.