http://www.perlmonks.org?node_id=437433

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

Hi all.

I was recently experimenting with a few perl related topics and I felt as though I might benefit from some clarification. In the following code sample:

#!/usr/bin/perl -w use strict; package Test; my $var = 15; package Test2; print $Test::var; print $var;

The output seems to indicate that a lexical variable (i.e. $var) is not associated with package level scope. I was able, however, to display the value of $var (15) by omitting the name of the initial package (Test). Only after using the package level 'qualifier' (our) was I able to obtain the value $var by prepending the package name.

Furthermore, there doesn't appear to be any safeguard that will prevent an interloper from creating subroutines within the namespace of neighboring (or distant) packages. Any feedback on these issues would be appreciated.

Thanks,
-Katie

Replies are listed 'Best First'.
Re: Packages, scope, and lexical variables
by Zaxo (Archbishop) on Mar 08, 2005 at 07:13 UTC

    Lexicals have file and block scope. Because they are not in the global symbol table, they are never identified with a namespace. Instead they live in a scratchpad which is created when a lexical scope is introduced.

    Nothing prevents someone from adding functions to your namespace. That could be viewed as a feature ;-)

    After Compline,
    Zaxo

Re: Packages, scope, and lexical variables.
by ikegami (Patriarch) on Mar 08, 2005 at 07:15 UTC
    The output seems to indicate that a lexical variable (i.e. $var) is not associated with package level scope.

    Correct. By definition, lexicals are block scoped and in no way related to packages. The file is considered a block for this purpose.

    If you want $Test::var to work, change my to our, making $var a package variable instead of a lexical.

    Furthermore, there doesn't appear to be any way to prevent an interloper from creating subroutines within the namespace of neighboring (or distant) packages.

    That's true, but I haven't known this to be a problem. Any of the following three lines of code would create a sub named new_sub in the package Test, no matter which file contained the code.

    { package Test; sub new_sub { ... } } -or- sub Test::new_sub { ... } -or- *Test::new_sub = sub { ... };
      Any of the following three lines of code would create a sub named new_sub in the package Test, no matter which file contained the code.
      Ah, but only the one with a package statement will necessarily use Test as the package for finding unqualified global variables. One-arg bless, caller() in called routines, and SUPER:: also will be affected, as well as probably other things that I'm unable to think of ATM. For all but trivial routines, using a proper package statement is best.

      The following demonstrates how Nopkg::Super is connected to it's containing package "Pkg", not to "Nopkg":

      $ cat pkg.pl use strict; use warnings; sub main::Duper { print "in main::Duper, called from pkg", scalar caller, "\n"; } @Pkg::ISA = "Super"; @Nopkg::ISA = "main"; sub Super::Duper { print "in Super::Duper, called from pkg ", scalar caller, "\n"; } { package Pkg; sub Nopkg::Duper { our @ISA; print "isa: @ISA\n"; my $obj = bless {}; print "blessed a ", ref($obj), "\n"; $obj->SUPER::Duper; } } Nopkg::Duper(); sthoenna@DHX98431 ~/pbed $ perl pkg.pl isa: Super blessed a Pkg in Super::Duper, called from pkg Pkg
        True. Thanks for eloborating.
Re: Packages, scope, and lexical variables
by merlyn (Sage) on Mar 08, 2005 at 13:55 UTC
    Everything you say is "by design" and "documented".

    Packages are a way to politely separate the global symbol table. Lexicals were introduced later in Perl history to have more traditional "private" variables.

    Because packages are global, there are no restrictions from any part of the code pushing to or pulling from any part of the global symbol table. Think of a package declaration as "in this area of this file, I don't have to type that silly package name in front of all my global names: Perl is doing it for me!". That's all it's doing, but if you spell out a package name explicitly, you're just doing the typing yourself.

    I have a column on the relationship of my, our, packages, and lexicals, and my Alpaca book also goes into the subject in greater depth.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

Re: Packages, scope, and lexical variables
by manav (Scribe) on Mar 08, 2005 at 08:12 UTC
    Relevant lines from perldoc -f our

    An "our" declaration declares a global variable that will be
    visible across its entire lexical scope, even across package
    boundaries
    . The package in .....


    Manav