Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Global variables in Perl

by taioba (Novice)
on Jun 03, 2010 at 17:05 UTC ( #842960=perlquestion: print w/ replies, xml ) Need Help??
taioba has asked for the wisdom of the Perl Monks concerning the following question:

Hi, monks! I already did my homework by looking at the global variable discussion in this website and I also perused countless other webpages with no success. I want to commit the gravest sin of all and export a global variable from a package. The reason why I do it is so I can turn on the debug switch by changing the value of the variable in one module and then get all the assertions and print statements working in myriad of scripts and modules of this project I am working on. So, I tried this, in ActivePerl 5.10.0 build 1004:

package ConfigThisJunk; use strict; use warnings; BEGIN { use Exporter; our @ISA = qw( Exporter ); our @EXPORT_OK = qw( $DEBUG ); } our $DEBUG = 1; 1;
SomeJunk.pl use strict; use warnings; our $DEBUG; use ConfigThisJunk qw ( $DEBUG ); print $DEBUG;

and I got 'Use of uninitialized value $DEBUG in print'. If I however replace the last line by:

print $ConfigThisJunk::DEBUG;

it works. I suppose I could remove 'use strict', which I prefer not to or initialize $DEBUG lexically as

our $DEBUG = $ConfigThisJunk::DEBUG;

but I'd really like to understand what I'm doing wrong. Any help will be greatly appreciated. Many thanks.

Comment on Global variables in Perl
Select or Download Code
Re: Global variables in Perl
by LanX (Canon) on Jun 03, 2010 at 17:17 UTC
    #### our $DEBUG; # don't use ConfigThisJunk qw ( $DEBUG ); print $DEBUG;

    our binds any use of the variable within the scope to the actual package, such that your print will try to access the undefined $main::DEBUG instead of $ConfigThisJunk::DEBUG

    Cheers Rolf

Re: Global variables in Perl
by ikegami (Pope) on Jun 03, 2010 at 17:48 UTC
    In laymen's terms, you're declaring two variables named $DEBUG.
    our $DEBUG; <-- 1 use ConfigThisJunk qw ( $DEBUG ); <-- 2

    The print sees the former. Get rid of our $DEBUG; in the main pacakge.

    As an aside, I suggest you change

    our $DEBUG = 1;
    to
    use vars qw( $DEBUG ); $DEBUG = 1;
    in order to avoid spurious "used only once" warnings if you decide to do
    use ConfigThisJunk; print $ConfigThisJunk::DEBUG;

      Thanx monks! However, I had to include the 'our' or 'use var' statement (I believe the second one is deprecated now) so that Perl wouldn't croak a 'Global symbol "$DEBUG" requires explicit package name at...' error. If I remove 'use strict' AND the 'our'|'use var' statement I get the same 'Use of uninitialized value $DEBUG in print at...' message as before. Perhaps a bug with Exporter? I also tried Exporter-Lite without success...

        I had to include the 'our' or 'use var' statement so that Perl wouldn't croak a 'Global symbol "$DEBUG" requires explicit package name at...' error.

        Not so.

        $ cat ConfigThisJunk.pm package ConfigThisJunk; use strict; use warnings; BEGIN { use Exporter; our @ISA = qw( Exporter ); our @EXPORT_OK = qw( $DEBUG ); } our $DEBUG = 1; 1; $ perl -wle'use strict; use ConfigThisJunk qw( $DEBUG ); print $DEBUG' 1

        I believe the second one is deprecated now

        Yeah, ignore that. They both have their uses. Think of it as "'our' is a better choice if both 'use vars' and 'our' fits your needs".

Re: Global variables in Perl
by ikegami (Pope) on Jun 03, 2010 at 19:15 UTC
    Thinking about 'our' vs 'use vars' made me wonder: Why are you using a var in the first place?
    package ConfigThisJunk; use strict; use warnings; use Exporter; our @ISA = qw( Exporter ); our @EXPORT_OK = qw( DEBUG ); use constant DEBUG => 1; 1;
    use strict; use warnings; use ConfigThisJunk qw( DEBUG ); my $x = 123; print("debug: x is $x\n") if DEBUG;

    Bonus: If DEBUG is false, the whole print-if is optimised away because it's a constant! (If it's true, the if part is optimised away.)

    If you wanted the be able to change DEBUG, this is still cleaner:

    package ConfigThisJunk; use strict; use warnings; use Exporter; our @ISA = qw( Exporter ); our @EXPORT_OK = qw( DEBUG ); my $DEBUG = 1; sub DEBUG { if (@_) { $DEBUG = shift; } return $DEBUG; } 1;
    use strict; use warnings; use ConfigThisJunk qw( DEBUG ); my $x = 123; print("debug: x is $x\n") if DEBUG;

      Thanks, ikegami! I guess the issue is with my installation of Perl. If I use DEBUG, it croaks at the use of a bareword when strict 'subs' is in use. I had tried 'use constant', before, it kept warning me that the subroutine DEBUG was re-defined somewhere, now the warning went away. But the idea of using a sub instead of a variable is indeed neat, as Ronald pointed out. I tried &DEBUG but it looks for main::DEBUG. I'll probably just declare $DEBUG lexically in all scripts and modules and assign the function stored in ConfigThisJunk.pm to that variable. Later, I'll switch to a Mac... Cheers!

        Please stop making claims about the code that's been posted based on different code that wasn't posted.

        If I use DEBUG, it croaks at the use of a bareword when strict 'subs' is in use.

        I don't believe you, not if you import the symbol as shown in both your code and my code.

        I tried &DEBUG but it looks for main::DEBUG.

        You must not have imported the symbol as shown.

        I'll probably just declare $DEBUG lexically in all scripts and modules and assign the function stored in ConfigThisJunk.pm to that variable

        That's silly. Just use the function. Import it as shown if you don't want to use the full name.

Re: Global variables in Perl
by rovf (Priest) on Jun 04, 2010 at 09:43 UTC
    The reason why I do it is so I can turn on the debug switch by changing the value of the variable in one module
    Which of course you could also do by using a lexical variable instead of a global one, plus providing a *function* which turns debugging on/off. The latter has the advantage that you could later hook in arbitrary actions to be executed when the debug state changes between on and off.


    -- 
    Ronald Fischer <ynnor@mm.st>

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (13)
As of 2014-08-27 21:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (253 votes), past polls