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

hi,

Using this:

use warnings; use strict; use Getopt::Long; # global variables my $warning = 90; my $critical = 30; my $version = 1; my $help = 0; my $host; my $revision; my $debug = undef; my $tag; Getopt::Long::Configure( "no_ignore_case", "bundling" ); GetOptions( 'H|host=s' => \$host, 't|tag=s' => \$tag, 'h|help|?' => \$help, 'v|verbose' => \$debug, 'V|version' => \$revision, 'w|warning=i' => \$warning, 'c|critical=i' => \$critical, ); if ( defined $debug ) { use SOAP::Lite +trace => "debug"; } else { use SOAP::Lite; }
When I run it like this:
./code -H localhost
it should not use the SOAP::Lite library with debugging enabled, but it does. I do not understand why. If I remove the if/else loop and just insert a use SOAP::Lite statement it works without debugging, but I would very much prefer to have the choice as a cli option, this script will be used by people who do not know how to debug Perl or any other programming language.

Any clue greatly appreciated. update: I also tried using

my $debug = undef;
but still no change

update 2: thank you for your (very) fast replies. I understand it now and it works great with the import suggestion. I learnt something today :-)

Replies are listed 'Best First'.
Re: defined weirdness
by Corion (Patriarch) on Nov 01, 2013 at 09:19 UTC

    The perceived weirdness is not with defined, but a side effect of how use works.

    Basically, use works at compile time, while your if statement is a runtime thing. The documentation for use also shows you what to do to import modules at runtime:

    if( ... ) { require Module; Module->import( ... ); };
Re: defined weirdness
by GrandFather (Saint) on Nov 01, 2013 at 09:32 UTC

    For a first step in understanding change your if statement to:

    if ( defined $debug ) { print "use SOAP::Lite +trace => 'debug'\n"; } else { print "use SOAP::Lite\n"; }

    With an empty command line it prints:

    use SOAP::Lite

    Now the why: use is processed at compile time so the first "use SOAP..." line is processed first and you get the debug version loaded. When your code runs following compile the use has already been executed so the if makes no difference to the outcome.

    Instead of "use", use require:

    if ( defined $debug ) { SOAP::Lite->import(trace => 'debug') if require SOAP::Lite; } else { SOAP::Lite->import() if require SOAP::Lite; }
    True laziness is hard work
Re: defined weirdness (use happens at compile time)
by Anonymous Monk on Nov 01, 2013 at 09:20 UTC
    Read use/require/import and you will understand that you cannot write if(something){use somethin; } because use happens always, at compile time

    use SOAP::Lite; if( $debug ){ SOAP::Lite->import( trace => 'debug ' ); }