Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Setting lexicals in a BEGIN block.

by mephit (Scribe)
on Jun 20, 2002 at 22:04 UTC ( [id://176172]=perlquestion: print w/replies, xml ) Need Help??

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

Greetings.

Quick background: I want to use a module if it exists, otherwise use another, then create a file-scoped lexical object of the appropriate class. This would best be done in a BEGIN block, I've figured out.

After a few Super Searches, I figured out a few ways to set a file-scoped variable within said BEGIN block, and I'm wondering which is the Best Way, or if it's just a matter of programmer preference.

I have all methods incorporated in the code snippet below, so I wouldn't have to illustrate things four times. They all work, except for the $our_var method. I find this odd, since a "use vars" variable works, but "our" doesn't. Aren't the two the same thing?

Thanks to tye and this node for pointing out that a 'my' var declared before a BEGIN block won't cause problems. I assumed that it wouldn't work, but it does. Yay.

Anyway, here's my code:

use strict; my $pre; BEGIN { my $closure; our $our_var; use vars qw/$vars/; if (eval {require CGI::Safe} ) { CGI::Safe->import(); $closure = CGI::Safe->new; $vars = CGI::Safe->new; $pre = CGI::Safe->new; $our_var = CGI::Safe->new; } else { $< = $>; delete @ENV{qw(IFS CDPATH ENV BASH_ENV SHELL PATH)}; require CGI; CGI->import( qw/ :standard / ); $CGI::DISABLE_UPLOADS = 1; $CGI::POST_MAX = 512 * 1024; $closure=CGI->new; $vars=CGI->new; $pre=CGI->new; $our_var=CGI->new; } sub get_obj { return $closure }; } my $q = get_obj(); printf "object in 'closure' method is of class %s\n", ref ($q); printf "object in 'usr vars' method is of class %s\n", ref ($vars); printf "object in 'my' method is of class %s\n", ref ($pre); #printf "object in 'our' method is of class %s\n", ref ($our_var);
So, which is best? Is that even a real closure? And why doesn't the $our_var method work? Thanks for any help, folks.

Mephit

--

There are 10 kinds of people -- those that understand binary, and those that don't.

Replies are listed 'Best First'.
Re: Setting lexicals in a BEGIN block.
by chromatic (Archbishop) on Jun 21, 2002 at 01:56 UTC
    get_obj() is a closure. Variables declared with 'our' are lexically scoped:
    use warnings; use strict; { our $foo = 1; } print $foo;

      Variables declared with 'our' are lexically scoped:

      Only their declaration is lexically scoped. The variable itself is a real global.

      use strict; use warnings; { our $foo = "Hello, world!\n"; } { print our $foo; # prints: Hello, world! }
      Only "my" variables are real lexicals:
      use strict; use warnings; { my $foo = "Hello, world!\n"; } { print my $foo; # warns: Use of uninitialized value }

      - Yes, I reinvent wheels.
      - Spam: Visit eurotraQ.
      

Re: Setting lexicals in a BEGIN block.
by Juerd (Abbot) on Jun 21, 2002 at 07:11 UTC

    After a few Super Searches, I figured out a few ways to set a file-scoped variable within said BEGIN block, and I'm wondering which is the Best Way, or if it's just a matter of programmer preference.

    It's more a programmer preference. I try to avoid setting lexicals in BEGIN blocks. If you do set a lexical, make sure it is declared before the BEGIN block, because otherwise, the variable will be lost forever (unless used in a closure like your get_obj).

    I find this odd, since a "use vars" variable works, but "our" doesn't. Aren't the two the same thing?

    The vars pragma is not block-scoped, but file scoped (this is documented, use the link). If you use "our" inside the block, you can use the variable unqualified (qualified is $Package::variable) in the block, but not outside of it. If you use "use vars" inside the block, you can use the variable everywhere in the file. You could move the "our" statement to some place before the block, or repeat the "our" elsewhere. The same variable will be used (a second "our $foo" does not create a new $foo), as it is a normal global.

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.
    

      The vars pragma is not block-scoped, but file scoped

      In fact, the documentation is a little off on that one. The vars pragma is neither block nor file scoped, it is package scoped.

        It's better to say that it isn't scoped at all. All the vars pragma does is, after some checking of arguments, is using the fully qualified variable in a dummy statement. There is no scoping involved.

        Abigail

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2024-04-26 00:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found