Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Best practice for setting module "environment" variables

by nysus (Parson)
on May 06, 2017 at 17:53 UTC ( [id://1189678]=perlquestion: print w/replies, xml ) Need Help??

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

I've written a module. When the module is running on machine X, I want a certain directory to be set to Y. When running on machine A, I want the directory to be B. I'm assuming that the best way to achieve this is through some kind of config file for the module. Instead of rolling my own solution, I'm guessing there is already a CPAN module for this. I'm familiar with Config::Simple but wondering if there might be something out there more specific for this task for setting "environment" variables for use with modules. Thanks.

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: Best practice for setting module "environment" variables
by shmem (Chancellor) on May 06, 2017 at 18:55 UTC

    I think that it is not a modules task to know on which machine it is run. There are Modules in the perl core which do different things depending on the operation system they are running on for the sake of portability, e.g. File::Spec. Instead in your case I'd place the burden on the shoulders of the module user, i.e. the code which uses the module. To set something in the module's namespace, write a import subroutine which does just that. You decide whether that variable is visible (and/or changeable) from the outside (our, or package global), or if it is a private variable to the module which can be set only once in the import routine.

    package Foo; my $dir; # could be 'our' to be visible from outside # portablitity... far from complete if ($^O eq 'MSWin32') { $dir = 'C:\Users'; } else { $dir = '/home'; } sub import { my $package = shift; # just the package name if (@_) { if (@_ % 2) { die "odd number of parameters in ".__PACKAGE__"::import(), + aborted"; } my %args = @_; if ($args{dir}) { $dir = $args{dir}; } } } ... # more module code 1;

    Code using this module would say use Foo dir => '/tmp_mnt/home' if it was running, say, on SunOS-4.1.3 and the home directories were mounted via NIS, NFS and automounter. I digress... but you get the picture ;-)

    Since use statements lead to compiling and executing the used module which the current script is parsed, any intialization of arguments to e.g. use Foo dir => $somedir must happen before use Foo is called, which means that this code must be IMMEDIATE (in forth terms). This is done wrapping the initializing code into a BEGIN block prior to use Foo. The contents of this block will be parsed and executed immediately.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Best practice for setting module "environment" variables
by Discipulus (Canon) on May 06, 2017 at 18:48 UTC
    Hello nysus,

    your question is a little smoky, for me.

    Config::Any and Config::General and JSON::MaybeXS are valid options to have a separate configuration.

    Also YAML can be used to have separate configuration.

    But perhaps it is better to specify to us what makes machine X different from machine A. Many modules has builtin for configuration using some exported (or anyway accessible using the full package qualified name) variable. This can sounds weird to someone but is, imhe, a frequent thing.

    Many others use effective %ENV vars to change their behaviour; this is vary basic but valid too.

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Best practice for setting module "environment" variables
by BillKSmith (Monsignor) on May 06, 2017 at 22:01 UTC
    Regardless of which mechanism you choose, I recommend that an initialization module set the configuration for each machine. The file should only specify the machine serial number, or similar identification. This prevents a casual user from putting your script in an invalid state.
    Bill
Re: Best practice for setting module "environment" variables
by kevbot (Vicar) on May 07, 2017 at 05:57 UTC
    Take a look at Config::ENV. Is this the type of thing you are looking for?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1189678]
Approved by Discipulus
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (8)
As of 2024-04-23 08:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found