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

Update:All problems have solutions and there's an explanation to my mystery below Re^2: Exporter (sometimes) doesn't seem to export if it's not first in @ISA:etadpU

I have a simple script:

#!/usr/bin/perl -w use Foo ; use Goo ; use Biz ; use Baz ; eval { &testfoo ; } ; warn $@ if $@ ; eval { &testgoo ; } ; warn $@ if $@ ; eval { &testbiz ; } ; warn $@ if $@ ; eval { &testbaz ; } ; warn $@ if $@ ;
with a few packages:
package Foo ; use base qw(Class::DBI) ; use vars qw(@ISA @EXPORT) ; require Exporter ; push @ISA, qw(Exporter) ; @EXPORT = qw/testfoo/ ; sub testfoo { print "It works\n" ; }
package Goo ; use base qw(Class::DBI) ; use vars qw(@ISA @EXPORT) ; require Exporter ; unshift @ISA, qw(Exporter) ; @EXPORT = qw/testgoo/ ; sub testgoo { print "It works\n" ; } 1 ;
package Biz ; use base qw(CGI) ; use vars qw(@ISA @EXPORT) ; require Exporter ; push @ISA, qw(Exporter) ; @EXPORT = qw/testbiz/ ; sub testbiz { print "It works\n" ; } 1 ;
package Baz ; use base qw(CGI) ; use vars qw(@ISA @EXPORT) ; require Exporter ; unshift @ISA, qw(Exporter) ; @EXPORT = qw/testbaz/ ; sub testbaz { print "It works\n" ; } 1 ;

Although they all look similar, my output is

$ perl test.pl It works It works Undefined subroutine &main::testbiz called at test.pl line 19. It works

Somehow, the location of "Exporter" within the ISA array makes a difference, and the difference is different if the other class in CGI or Class::DBI. It also seems to be different on different machines I use. My Mac produces the output above. I've got one Linux machine that gives the same result and another that gives the error whenever Exporter is listed second. I can't say what all the differences are between the machines; they're "pretty similar" but obviously something's different.

About the machines: They're more different than I thought, but not in any pattern I can see.

On Linux #1 (the "bad" one):

[mcdave@maia ~]$ uname -a Linux maia 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x +86_64 x86_64 GNU/Linux [mcdave@maia ~]$ perl -v This is perl, v5.8.8 built for x86_64-linux-thread-multi ... [mcdave@maia ~]$ perl -MExporter -e 'print $Exporter::VERSION, "\n"' 5.63 [mcdave@maia ~]$ perl -MCGI -e 'print $CGI::VERSION, "\n"' 3.15 [mcdave@maia ~]$ perl -MClass::DBI -e 'print $Class::DBI::VERSION, "\n +"' 3.0.17 [mcdave@maia ~]$ perl test.pl Undefined subroutine &main::testfoo called at test.pl line 9. It works Undefined subroutine &main::testbiz called at test.pl line 19. It works

On Linux #2 (the "good" one):

[mcdave@trowel ~]$ uname -a Linux trowel 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 + x86_64 x86_64 GNU/Linux [mcdave@trowel ~]$ perl -v This is perl, v5.8.8 built for x86_64-linux-thread-multi ... [mcdave@trowel ~]$ perl -MExporter -e 'print $Exporter::VERSION, "\n"' 5.58 [mcdave@trowel ~]$ perl -MCGI -e 'print $CGI::VERSION, "\n"' 3.15 [mcdave@trowel ~]$ perl -MClass::DBI -e 'print $Class::DBI::VERSION, " +\n"' 3.0.17 [mcdave@trowel ~]$ perl test.pl It works It works Undefined subroutine &main::testbiz called at test.pl line 19. It works

Update: the real difference appears to be neither in Exporter nor Class::DBI nor CGI. The CGI piece was an interesting red herring in my original problem, and I've learned something about Exporter now. But the real, interesting difference was down in one of the superclasses of Class::DBI. Namely, Class::Accessor was version 0.34 on the "bad" machine and version 0.33 on the "good" machine.

Replies are listed 'Best First'.
Re: Exporter (sometimes) doesn't seem to export if it's not first in @ISA
by ikegami (Pope) on Apr 15, 2010 at 03:30 UTC
    use Module; -and- use Module qw( ... );
    are basically the same as
    BEGIN { require Module; Module->import(); } -and- BEGIN { require Module; Module->import(qw( ... )); }

    Your module doesn't have an import method, so the modules in @ISA are searched for one. Both CGI and Exporter have an import function, so the one that will be called will be controlled by the order of the classes in @ISA.

    If you want Exporter's import, put Exporter early enough in @ISA or add the following to your module:

    { no warnings 'once'; *import = \&Exporter::import; }

    (For what it's worth, I've always thought Exporter's reliance on inheritance is dumb.)

      That's interesting and very clear. And it led me straight to the solution for my particular case about Class::DBI on the different machines. Both have version 3.0.17 of Class::DBI, but on Linux #1:

      [mcdave@maia ~perl -MClass::DBI -MClass::ISA -e 'foreach $f (Class::IS +A::super_path("Class::DBI")) { print join(" ", $f, ${"${f}::VERSION"} +, "\n" ) ;}' Class::DBI::__::Base -1, set by base.pm Class::Accessor 0.34 Class::Data::Inheritable 0.08 Ima::DBI 0.35 [mcdave@maia ~]$ perl -MClass::DBI -e 'print Class::DBI->can("import") + ? "yes" : "no", "\n"' yes
      but on Linux #2:
      [mcdave@trowel ~]$ perl -MClass::DBI -MClass::ISA -e 'foreach $f (Clas +s::ISA::super_path("Class::DBI")) { print join(" ", $f, ${"${f}::VERS +ION"}, "\n" ) ;}' Class::DBI::__::Base -1, set by base.pm Class::Accessor 0.33 Class::Data::Inheritable 0.08 Ima::DBI 0.35 [mcdave@trowel ~]$ perl -MClass::DBI -e 'if( Class::DBI->can("import" +) ) { print "yes" } else { print "no" }; print "\n"' no
      So I conclude that the "difference" is in Class::Accessor!

      Thanks for your clear explanation

Re: Exporter (sometimes) doesn't seem to export if it's not first in @ISA
by ww (Archbishop) on Apr 15, 2010 at 03:32 UTC
    You don't need to say "all the differences" but it might be illuminating to know (i.e., you should check and update your question) the version of Perl on each machine (perl -v) and the version of Exporter, again, on each machine, id'ed by OS/vers.