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

I've run into some odd Exporter errors. Exported functions are working fine in some modules, but not in others. Possibly a load order dependency?

An example exporting module:

package MyNameSpace::Faction; ... BEGIN { #use Exporter 'import'; use Exporter qw (import); #@MyNameSpace::Faction::ISA = qw(MyNameSpace::Player Exporter); #@MyNameSpace::Faction::ISA = qw(Exporter MyNameSpace::Player); @MyNameSpace::Faction::ISA = qw(MyNameSpace::Player); @MyNameSpace::Faction::EXPORT_OK = qw( &get_faction &max_faction ); }

(As you can see from the commented-out lines, I've tried several syntactic variations for calling Exporter, but they haven't made any difference.)

Calling module 1:

package MyNameSpace::Player; ... use MyNameSpace::Faction qw (get_faction); ... $self->{faction} = get_faction($faction);

This produces Undefined subroutine &MyNameSpace::Player::get_faction called at [the last line included above] when I try to use the module.

Calling module 2:

package MyNameSpace::Territory; ... use MyNameSpace::Faction qw (get_faction); ... $self->{faction} = get_faction($faction);

This works perfectly fine.

Both reference the same package and import it with identical use statements, yet one successfully imports get_faction and the other doesn't. How do I track this down and resolve it? I know I can work around it by changing the failing line to $self->{faction} = MyNameSpace::Faction::get_faction($faction);, but that neither explains nor resolves the inconsistency of why Territory imports get_faction and Player doesn't.

(This may not be the best example, as it looks a little circular (Faction isa Player and exports the function that Player fails to import), but I've run into similar issues between otherwise unrelated modules, so I'm fairly sure that circularity isn't the cause. This example is just the one I recently encountered and finally drove me to ask about it.)

Replies are listed 'Best First'.
Re: EXPORT_OKed function refusing to import
by ikegami (Patriarch) on Feb 06, 2007 at 20:20 UTC

    I presume you use use MyNameSpace::Faction ...; in Player and use MyNameSpace::Player ...; in Faction? If so, something I previously wrote should help you.

    If ModA uses ModB, ModB uses ModA, and ModA or ModB exports symbols, one needs to pay attention to code execution order. The best way I've found to avoid problems is to do:

    # ModA.pm use strict; use warnings; package ModA; BEGIN { our @ISA = qw( ... ); our @EXPORT_OK = qw( ... ); require Exporter; *import = \&Exporter::import; } use This; use ModB; use That; ... 1;
    # ModB.pm use strict; use warnings; package ModB; BEGIN { our @ISA = qw( ... ); our @EXPORT_OK = qw( ... ); require Exporter; *import = \&Exporter::import; } use This; use ModA; use That; ... 1;
      Hmmm... Very interesting. I was under the impression that all the BEGIN blocks would run first, unconditionally, so it wouldn't matter where they were placed in the source file, but moving them to before my use lines seems to have cleared this right up. Thanks!
        use Foo qw( bar );

        is a shortcut for

        BEGIN { require Foo; Foo->import(qw( bar )); }