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

How is 'strict' used with modules that that create variable such as Env and maybe Opt?
use Env; use strict; if ( defined $SHELL) { print "$SHELL\n"; } root@whitebox:/tmp# perl testEnv.pl /bin/bash
With the 'if' clause in the code, all is well as long as there is such an environment value. But if the possible value isn't in the environment (e.g. EGGSHELL is not defined):
use Env; use strict; if ( defined $EGGSHELL) { print "$EGGSHELL\n"; } root@whitebox:/tmp# perl testEnv.pl Global symbol "$EGGSHELL" requires explicit package name at testEnv.pl + line 4. Execution of testEnv.pl aborted due to compilation errors.

What is the correct explicit package, and if Env, what is the correct syntax?

Replies are listed 'Best First'.
Re: Can't be 'strict' with Env ??
by ikegami (Patriarch) on Jan 24, 2007 at 20:52 UTC

    The Why

    It behaves this way to avoid misleading error messages. Imagine that use Env; did what you want.

    >perl -le "use strict; use Env; print $CONFIG;" Global symbol "$CONFIG" requires explicit package name

    You should give a better error message or use a default when the variable isn't specified.

    Workarounds

    Just specify the variables you wish to import.

    >perl -le "use strict; use Env qw( $WINDIR ); print $WINDIR;" E:\WINNT

    Or declare the variable.

    >perl -le "use strict; use Env; our $WINDIR; print $WINDIR;" E:\WINNT

    Of course, there's always $ENV{WINDIR}.

    >perl -le "use strict; print $ENV{WINDIR};" E:\WINNT

    Update: Added the reason for this behaviour.

Re: Can't be 'strict' with Env ??
by liverpole (Monsignor) on Jan 24, 2007 at 20:50 UTC
    Hi Wiggins,

    Just specify which environment variable(s) you wish to use:

    use strict; use warnings; use Env qw/EGGSHELL/; + if (defined $EGGSHELL) { print "$EGGSHELL\n"; } else { print "EGGSHELL not defined in \%ENV\n"; }

    And then (for example):

    [liverpole@golux ~]% perl envtest EGGSHELL not defined in %ENV [liverpole@golux ~]% setenv EGGSHELL 1379 [liverpole@golux ~]% perl envtest 1379

    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: Can't be 'strict' with Env ??
by jettero (Monsignor) on Jan 24, 2007 at 20:45 UTC
    Personally, I tend to juse use "$ENV{SHELL}" to get at "$SHELL." Then you could do "if( exists $ENV{SHELL} )" instead.

    ... but all you need to make yours go is "our $SHELL" and you should be all set.

    -Paul

Re: Can't be 'strict' with Env ??
by Zaxo (Archbishop) on Jan 24, 2007 at 20:45 UTC

    The trick is to decide what you need from %ENV and either detaint it or set it explicitly. The perlsec pod tells about how to do that.

    Make sure to do it in a BEGIN block before loading Env.pm.

    Update: Whoops! I had taint on the mind, this doesn't answer your question (though I insist it's good to know :-). As jettero says, our is the answer, or use vars ($FOO, $BAR);

    After Compline,
    Zaxo

Re: Can't be 'strict' with Env ??
by Wiggins (Hermit) on Jan 25, 2007 at 14:03 UTC
    These are all good answers. For the sake of brevity, I asked the specific question. The general question has to to do with 'strict' and variables the programmer doesn't directly create.

    I gave up trying to be strict with a program that used 'getopt' that created variables for commnad line options. I knew what was comming, so extra effort to get thenm scoped properly just seemed wrong (and I couldn't figure it out).

    But the explicit naming in the export fits the bill nicely in that it tells me when I try something I didn't plan. Thanks all. Now another tool in the box.