in reply to Re: Lexical and dynamic scope confusion!
in thread Lexical and dynamic scope confusion!

Just a few comments on your example. The first one is that to do what you want to do within a single file, you need to stick the initializations of @EXPORT and @EXPORT_OK in their own BEGIN block (otherwise they happen at runtime, which is to late for the (require-less) importation from Foo). To see this, try running your code with the line defining main::sub1 commented out. It fails with the error

Undefined subroutine &main::sub1...
even though you are importing from Foo and Foo exports a routine sub1. But if you put the initialization of @EXPORT in a BEGIN block, the code runs fine and you see the output:
Foo::sub1
(OK, I don't want to confuse anyone, so just to be perfectly clear, this business of sticking the initialization of @EXPORT (and @EXPORT_OK, @EXPORT_FAIL, etc.) in a BEGIN block is necessary here only because we are trying to "import" from within the same file, which is a very unnatural thing to do, and meant only for the purpose of testing and illustration.)

If now you uncomment the definition of main::sub1 the code compiles and runs, but one gets a warning about redefining "sub1" (main::sub1 that is) that one didn't get before. (Which suggests that in the original version there really wasn't even the potential for conflict between the two sub1's, since Foo wasn't really exporting it after all.)

A second point is that if (after putting @EXPORT, etc. in a BEGIN block) one puts the importing of Foo::sub1 after the definition of main::sub1, this will cause main::sub1 to be aliased to Foo:sub1 (as Exporter normally does), and no warning is emitted. To see this, try running the following code:

use strict; use warnings; package Foo; use base 'Exporter'; BEGIN { our @EXPORT = qw(sub1); } sub sub1 { print "Foo::sub1\n"; } package main; sub sub1 { print "main::sub1\n"; } BEGIN { Foo->import(); } sub1(); main::sub1();

The third point is that mentioning the same subroutine in both @EXPORT and @EXPORT_OK, as is the case with sub1 in the original example, defeats the purpose of @EXPORT_OK (namely to export only if the user explicitly requests it). In the the original example, Foo exports sub1 unconditionally, even though sub1 is mentioned in EXPORT_OK.

the lowliest monk

Update: Added a brief explanation in the first paragraph for why an extra BEGIN block is needed.