Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

What's the right way to include a config file as a .pm bareword?

by Cody Fendant (Hermit)
on Aug 07, 2015 at 07:27 UTC ( [id://1137798]=perlquestion: print w/replies, xml ) Need Help??

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

I'm looking at Perl::Critic and it's complaining about my use of a simple config.pl file.

I have code which needs to be told certain file paths and URLs, and I store those in a simple hash in a .pl file which looks like this:

$config = { foo => 'bar', baz => 'bax' }

and I require it it as follows:

our ($config); require '/path/to/config.pl';

Then I can just use $config->{foo} in my script.

So what's the simplest version of that which will satisfy Perl::Critic? It wants me to use something like My::Module::Config, but that's overkill for my purposes really. I don't need to create a module.

Replies are listed 'Best First'.
Re: What's the right way to include a config file as a .pm bareword?
by Corion (Patriarch) on Aug 07, 2015 at 07:37 UTC

    Also consider if you need to have (two) different configuration files at the same time.

    I would ditch or disable the Perl::Critic rule that prohibits a direct require.

Re: What's the right way to include a config file as a .pm bareword?
by Anonymous Monk on Aug 07, 2015 at 10:28 UTC

    PerlCritic rules are sometimes just good suggestions, and often the experienced programmer will know better.

    $ perlcritic --verbose 11 foo.pl "require" statement with library name as string at line 6, near 'requi +re '/tmp/config.pl';'. Modules::RequireBarewordIncludes (Severity: 5) When including another module (or library) via the `require' or `u +se' statements, it is best to identify the module (or library) using a bareword rather than an explicit path. This is because paths are u +sually not portable from one machine to another. Also, Perl automatically assumes that the filename ends in '.pm' when the library is expres +sed as a bareword. So as a side-effect, this Policy encourages people to +write '*.pm' modules instead of the old-school '*.pl' libraries. use 'My/Perl/Module.pm'; #not ok use My::Perl::Module; #ok

    So this means the rule exists because its author(s) were worried that people are writing Perl-4-style libraries. Since in this case you know better and config.pl is not a library, you are free to overrule PerlCritic:

    require '/tmp/config.pl'; ## no critic (RequireBarewordIncludes)

    Of course there are other ways to "fix" the issue, e.g. to use do or even eval (but require is fine). Also, you could just turn config.pl into MyConfig.pm and make things easier that way too.

Re: What's the right way to include a config file as a .pm bareword?
by 1nickt (Canon) on Aug 07, 2015 at 11:29 UTC

    Why use Perl::Critic if you don't want to follow its advice?

    Using require to load a configuration file is a bad idea. For one thing it will silently fail to load the file into more than one package. From the docs for require:

    Otherwise, require demands that a library file be included if it hasn't already been included. ... Note that the file will not be included twice under the same specified name.

    $ cat conf.pl #!/usr/bin/perl use strict; use warnings; our %conf = ( foo => 'bar', baz => 'quux' ); __END__
    $ cat ONE.pm package ONE; use strict; use warnings; sub one { our %conf; require 'conf.pl'; return $conf{'foo'}; } 1;
    $ cat TWO.pm package TWO; use strict; use warnings; sub two { our %conf; require 'conf.pl'; return $conf{'baz'}; } 1;
    $ cat 1137798.pl #!/usr/bin/perl -w use strict; use ONE; use TWO; print ONE::one, "\n"; print TWO::two, "\n"; __END__

    Output:

    $ perl 1137798.pl bar Use of uninitialized value in print at 1137798.pl line 8.

    Change the require calls to do as somebody else noted and you can then import your config file into more than one package, which is useful.

    $ cat ONE.pm package ONE; use strict; use warnings; sub one { our %conf; #require 'conf.pl'; do 'conf.pl'; return $conf{'foo'}; } 1;
    $ cat TWO.pm package TWO; use strict; use warnings; sub two { our %conf; #require 'conf.pl'; do 'conf.pl'; return $conf{'baz'}; } 1;
    $ perl 1137798.pl bar quux

    So use do, or better yet, just use Config::Tiny, which exists to solve your problem.

    $ cat conf.ini [path] foo=bar some=other [url] baz=quux less=more
    $ cat 1137798-2.pl #!/usr/bin/perl -w use strict; use Config::Tiny; my $conf = Config::Tiny->read( 'conf.ini' ); print $conf->{path}->{foo}, "\n"; print $conf->{url}->{baz}, "\n"; __END__

    Output:

    $ perl 1137798-2.pl bar quux

    Now what's overkill about that?

    The way forward always starts with a minimal test.
Re: What's the right way to include a config file as a .pm bareword?
by Monk::Thomas (Friar) on Aug 07, 2015 at 09:57 UTC
    You can tell PerlCritic to stop complaining about this particular instance:
    require '/path/to/config.pl'; ## no critic (Rule name)
Re: What's the right way to include a config file as a .pm bareword?
by vinoth.ree (Monsignor) on Aug 07, 2015 at 08:03 UTC

    Even you can use do() to include .pl file, as below.

    use strict; use warnings; use Data::Dumper; our $config = do '/pathto/config.pl'; print $config->{'foo'};

    All is well. I learn by answering your questions...
Re: What's the right way to include a config file as a .pm bareword?
by afoken (Chancellor) on Aug 07, 2015 at 18:05 UTC

    Why using unlimited executable code in a config file is a bad idea: Re^2: conf file in Perl syntax.

    Use a non-executable configuration, as 1nickt++ explained. If you don't like Config::Tiny, or if INI files are too simple for your configuration, consider using JSON (e.g. using JSON::XS), XML (with the help of e.g. XML::LibXML), or YAML.

    All of these formats contain no executable code.

    Update (2015-08-09): YAML can contain executable code. Depending on how you configure the YAML reader, parts of the configuration file may be executed. So don't use YAML until you know how to prevent the YAML reader from executing code from the YAML file.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: What's the right way to include a config file as a .pm bareword to satisfy a Perl::Critic rule ? ( Module::Load::load() )
by Anonymous Monk on Aug 07, 2015 at 08:47 UTC
    Perl::Critic rules are very simple to circumvent satisfy textually as its mostly string matching, so use an intermediary, use Module::Load

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-04-25 02:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found