in reply to Lexical and dynamic scope confusion!

A little trial and error would answer the question as to what happens, although maybe not the "why" part. Here's what I wrote:

use strict; use warnings; package Foo; use base 'Exporter'; our @EXPORT = qw(sub1); our @EXPORT_OK = qw(sub1 sub2); sub sub1 { print "Foo::sub1\n"; } sub sub2 { print "Foo::sub2\n"; } package main; #use Foo; BEGIN { Foo->import(); } sub sub1 { print "main::sub1\n"; } sub1();
Note the "use Foo" is commented out - because I put this all in the same file, you can't quite do that, so I faked it with the next line - and the BEGIN is very important here. By using the BEGIN, it changed the output. With the BEGIN, I get "main::sub1" as the output, but without the BEGIN, I get "Foo::sub1" as the output.

With the BEGIN is representative of "use"ing the module since "use" is handled during compilation, as is anything in a BEGIN block.

I know others disagree with this, but the way I handle the ambiguity is to try to import as little as possible into my namespace - preferably importing nothing. And then I can call functions in other namespaces by fully qualifying the function call.

Even better than that is to use an OO interface, if there is one available, but not everything makes sense as an object. (I think CGI does, but that's not necessarily universally accepted, either.)

In absense of these (calling functions via fully qualified names, or OO syntax), import precisely what you need, no more, no less. This means you get to keep an exact list of what you're using from another module, and won't be as likely to have two functions in your module's namespace with the same name.

It is highly discouraged to try to use a function "sub1" from another module, while exporting a different "sub1" from your own module. You're looking for a headache on that one - fully qualified names (for calling the other module's sub1, not for exporting your sub1) or OO syntax are quite a bit cleaner here.

Replies are listed 'Best First'.
Re^2: Lexical and dynamic scope confusion!
by tlm (Prior) on Mar 27, 2005 at 15:58 UTC

    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.