in reply to scope with multiple files

Well, I couldn't figure out how to make it TAINT safe. Taint complains pretty much any time you try to execute code you are importing from somewhere else (at least, that's my understanding).

What you should be doing is eval'ing the configuration file. Below, I read in the config.pl file into a scalar, eval it, and pop the results into the $conf hash reference.

#!/usr/bin/perl -w use strict; my $config_file=(""); # declare this way to prevent warnings open(RE,"config.pl") || die("cannot open config.txt"); while(my $line=<RE>){ $config_file .= $line; } close(RE); my $conf = eval($config_file); # you can look at $@ after #this to see if eval had any errors! print $conf->{'var1'}, "\n"; print $conf->{'var2'}, "\n";
If you have a LOT of configuration information, you might want to look at something like XML::Simple, which will allow you to create a clean* looking configuration file and use it in your script pretty easily.

* XML is a two-edged sword. It CAN be clean, but you can make it look ugly if you try :)
-oakbox

Replies are listed 'Best First'.
Re: Re: scope with multiple files
by IOrdy (Friar) on May 22, 2002 at 15:40 UTC
    Yep I think XML is good for this.

    Here is a module I wrote the other day and I use it all the time now (I have a php version also that reads the same config files). Sure it's simple but it gets the job done. Requires XML::LibXML.
    package XML::Config; use strict; use XML::LibXML; use vars qw($VERSION); $VERSION = '0.02'; sub new { my ($proto) = shift; my $class = ref($proto) || $proto; # was it a hash or hashref passed. my $options; if (UNIVERSAL::isa($_[0], 'HASH')) { $options = shift; } else { $options = {@_}; } # check if config file defined and exists. my $file = $options->{file} || die(message => 'no config file defi +ned'); (-r $file) || die('could not find config file'); # parse then get xml data root; my $parser = XML::LibXML->new(); my $doc = $parser->parse_file($file); my $xml_r = $doc->getDocumentElement; # check to see if config file and has types defined. my $types = $xml_r->findvalue('/config/@types'); if (!defined($types)) { die('config file must contain types defini +tion') }; # load all config data into hash reference my $self = {}; foreach my $type (split /,/, $types) { #trim whitespace from each type $type =~ s/^\s*(.*?)\s*$/$1/; foreach my $node ($xml_r->findnodes('//'.$type)) { if (defined($node->findnodes('@name'))){ if (!defined($node->findvalue('text()')) || $node->fin +dvalue('text()') eq ' ' || !defined($node->findvalue('text()'))) { $self->{$type}->{$node->findvalue('@name')} = unde +f; } else { $self->{$type}->{$node->findvalue('@name')} = $nod +e->findvalue('text()'); } } } } # Not needed yet (will need to bless later) # bless($self, $class); return $self; } 1; __END__ =head1 NAME B<XML::Config> - Simple XML to hash reference conversion. But it's han +dy! =head1 SYNOPSIS Example XML config file: <config types="directory, value, message"> <directory name="dir">/xmilo/data</directory> <value name="val">foobar</value> <message name="msg">this is a message</message> </config> Now write some perl: #!/usr/bin/perl -w use strict; use XML::Config; my $config = XML::Config->new( file => '/home/iordy/public_html/xmilo/data/config.xml' ); my $dir = $config->{directory}->{dir}; #$dir == '/xmilo/data'; my $msg = $config->{message}->{msg}; #$msg == 'this is a message +'; my $var = $config->{value}->{val}; #$var == 'foobar'; =head1 DESCRIPTION This module attempts to make loading config files simpler, more unifor +m and language independant (the config file not the module). Sure it's just +an XML to hash reference conversion but it's handy! This module is licensed under the GPL. See the LICENSE section below for more details. =head1 TAGS The config file layout is very simple, there is only one tag that must + be in the config file, ironically it's <config> :) <config types="foo, bar"> <my_config> <!-- some directories --> <foo name="dir">/xmilo/data</foo> <foo name="home">/home/iordy/</foo> <!-- some other directories --> <bar name="lib">/home/iordy/lib</bar> </my_config> </config> =head2 <config> <config> defines a config area of any XML document, this must containt the types="" attribute with a comma delimited list of the types the module will look for. Example: If you plan on using the xml tags: <foo name="myfoo">this is my foo</foo> <bar name="mybar">this is my bar</bar> Then your config tag will look like: <config types="foo, bar">config content</config> =head1 METHODS =head2 new() Call new with a filename and it will return a hash of config value +s: my $config = XML::Config->new( file => '/home/iordy/config.xml' ); =head2 get() At the moment there is not get() method because it's simpler to ju +st return a hash reference. If for some reason it becomes worthwhile +it's easy to add later. Example: my $example = $config->{type}->{name}; =head1 WEBSITE You can find out more info here: http://www.iordy.com =head1 AUTHOR Shane Hanna (iordy@iordy.com) =head1 LICENSE XML::Config; Store your stuff in XML. Copyright (C) 2002 Shane Hanna (iordy@iordy.com) This module is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later v +ersion. =cut