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

Good morning,

I was trying to find out how Exporter manages to prevent the calling module from "strict vars" errors, so that the calling module may use the imported variables without declaring them.

So I wrote a file called "imp.pl":

package imp; *main::foo = \42;

Then I tried

perl -le 'BEGIN { require "imp.pl"}; use strict; print $foo'
and it printed 42. Now that's cool: I may use $foo without declaring it, merely because it exists in my namespace.

However, removing the first line "package imp;" from imp.pl, I get those errors:

perl -le 'BEGIN { require "imp.pl"}; use strict; print $foo' Variable "$foo" is not imported at -e line 1. Global symbol "$foo" requires explicit package name at -e line 1. Execution of -e aborted due to compilation errors.

So, the exporting doesn't work within the "main" package, which appears very strange to me. Even more curious, perl does seem to recognize that I tried to import the variable, because it prints "...is not imported...". This warning isn't printed for other variables:

perl -le 'BEGIN { require "imp.pl"}; use strict; print $bar' Global symbol "$bar" requires explicit package name at -e line 1. Execution of -e aborted due to compilation errors.

Extract from perldiag:

Variable "%s" is not imported%s
(F) While "use strict" in effect, you referred to a global variable that you apparently thought was imported from another module, because something else of the same name (usually a subroutine) is exported by that module. It usually means you put the wrong funny character on the front of your variable.

Obviously, I did not put the wrong funny character.

Could anyone please shed light into this darkness of perl's? Thank you very much.

Update: Using perl -MO=Deparse on imp.pl, I see that *main::foo is optimized to *foo. However, without a package line, this shouldn't make any difference.

Replies are listed 'Best First'.
Re: How to trick strict like Exporter does
by diotalevi (Canon) on Jul 12, 2006 at 13:24 UTC

    If you're going to import, you have to do it from a different package than the one you're importing to. That's how you avoid that warning you complained of. The *main::foo vs *foo thing is a red herring. It's just a syntax difference if the current package is main. Even if you weren't in main, *main::foo and *::foo would also just be syntax and not meaningfully different.

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      but what's the difference? the symbol table of main:: is the same in both cases. at which point is the difference strict is complaining about? without strict it's working.