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

Hi Monks! Why does this work?
$ cat test1.pl #! /usr/bin/perl use warnings; use strict; use vars qw( $name ); $name = 'Matt'; require 'test2.pl'; $ cat test2.pl #! /usr/bin/perl use warnings; use strict; print "Hello, $name!\n"; 1; $ ./test1.pl Hello, Matt! $ perl -c test2.pl Global symbol "$name" requires explicit package name at test2.pl line +6. test2.pl had compilation errors.

I'm working with some legacy code that depends on this behavior, so I'd like to know if it's a Good Thing.

What's really happening here, in terms of package variables, namespaces, symbol tables, and importing? An 'RTFM' is fine, as long as you tell me which 'FM'. ;)

Thanks in advance!

-- Matt

Replies are listed 'Best First'.
Re: 'use strict' and sharing globals between files
by ikegami (Patriarch) on Apr 07, 2009 at 20:46 UTC
    use vars isn't lexically scoped. $name is now "safe" to use from any code compiled in main:: (the namespace from which use vars was called).
Re: 'use strict' and sharing globals between files
by QM (Parson) on Apr 07, 2009 at 20:56 UTC
    test1.pl requires test2.pl, so test2.pl "runs" in test1.pl's namespace. In that context, $name is declared.

    Or, look at it another way: test2.pl isn't run without test1.pl's context, and doesn't necessarily compile without it either.

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

Re: 'use strict' and sharing globals between files
by morgon (Priest) on Apr 07, 2009 at 21:58 UTC
    When run under "strict" variables have to be declared before they can be used (with the exception of some - or a rather a lot :-) built-ins like $_, @_ etc.

    Now there are two types of variables in Perl: Package variables and lexical variables.

    Lexial variables are declared with "my" and don't live in a namespace.

    Package variables all live in a namespace and are declared either with "use vars" or with "our".

    A namespace is introduced with a "package" declaration or it defaults to "main::" when there is no package-declaration.

    In your case the second file uses strict and refers to a non-declared variable $name which is why it won't compile.

    test1 declares the $name variable to be a package variable ("use vars") in the main-namespace (as there is no package-declaration).

    Then test1 requires test2 (see perldoc -f require) which (as an approximation) loads, compiles and executes the 2nd script in the context where the require appears - i.e. in a context where we actually have a declared $name-variable (both files lack a package-declaration and so in both files unqualified (i.e. without explicit namespace) variables (like $name) belong to the "main"-namespace. This is why you can run test1.

    Incidentally this only works with package-variables. If you change the "use vars qw($name)" to "my $name" both files fail as lexical variables cannot be seen in the required file.

    hth

      Thanks to all three of you for your replies! I like to understand what's going on "under the hood" when I can, and now I'm a little closer. :)