Reputation: 301
I've wasted many days on a larger block of code, containing Exporter
statements, which used to work about a year ago. Several variations on this have failed, including an install of ./FOO/BAR/Foobar.pm
which signaled success.
I am using Windows 10, Perl v5.26.0, built for MSWin32-x64-multi-thread
#!/usr/bin/perl
use lib ".";
use lib "./FOO/BAR";
use strict;
use warnings;
use FOO::BAR::Foobar;
print "try FOO::BAR::Foobar::foo()\n";
FOO::BAR::Foobar::foo(); # perl can't find this
print "try foo()\n";
foo(); # errors out - can't find &main::foo
print "done\n";
#!/usr/bin/perl -w
use strict;
use warnings;
package Foobar;
our($VERSION , @ISA , @EXPORT , @EXPORT_OK , %EXPORT_TAGS , $FOO);
BEGIN {
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(foo);
}
sub foo {
print "Loaded\n";
$FOO = q{some val};
}
1;
perl Caller.pl
try FOO::BAR::Foobar::foo()
Undefined subroutine &FOO::BAR::Foobar::foo called at Caller.pl line 12.
What's going on? Should I abandon any use of Exporter
? But then how to link functions across modules?
Upvotes: 1
Views: 82
Reputation: 3013
There are three things going wrong:
With FOO::BAR::Foobar::foo()
: There is no such sub
, there is only Foobar::foo()
.
With foo()
: use FOO::BAR::Foobar;
is the equivalent of BEGIN { require FOO::BAR::Foobar; FOO::BAR::Foobar->import() }
, but there is no method import
available in the package FOO::BAR::Foobar
, since you're inheriting Exporter
into the package Foobar
.
With foo()
: You're using @EXPORT_OK
instead of @EXPORT
, which means that you need to explicitly import foo
, but you're not doing that in use FOO::BAR::Foobar;
.
So two things are needed to fix this:
As already pointed out in the comment by @HåkonHægland, change package Foobar;
to package FOO::BAR::Foobar;
.
Change use FOO::BAR::Foobar;
to use FOO::BAR::Foobar qw/foo/;
.
Then the code you've shown will work - there's no need to abandon Exporter
. I'd just recommend a different style of using Exporter
: Instead of inheriting via @ISA
, just import import
into your package. Here's how I would have written your file ./FOO/BAR/Foobar.pm
:
package FOO::BAR::Foobar;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT_OK = qw(foo);
our $FOO;
sub foo {
print "Loaded\n";
$FOO = q{some val};
}
1;
Upvotes: 4