Obscure baffling "module not exported" error: can someone help mefind the cause?
am 31.01.2008 21:20:25 von Henry LawI have a bizarre problem with packages and I'm hoping that someone can
help me find out what I'm doing wrong because I'm utterly stumped.
The error is "not exported" for something that quite clearly is exported
(details follow). The error disappears when one of several particular
lines is deleted or commented out, one of which refers to a different
Perl module altogether, not used anywhere in any of the code except for
the "use" statement. And yet that completely unused module is specific
to the error: simply replacing it with another, equally unused, module
causes the error to disappear. Again, more details below.
It's the most perplexing thing I've seen in all my years of debugging
hardware and software systems and I'm forced to the conclusion that
there's some corruption in the Perl installation itself, especially
since the code compiles clean on another machine at ostensibly the same
level (though the offending machine is newly-built). If someone can even
point me in the direction of something to look at or try I'd be grateful.
Now for the description of the code itself, which is a bit involved,
despite my having condensed it down to its bare essentials. If you're
prepared to help me make sense of this then
http://www.lawshouse.org/perl/Problem.jpg shows the thing
diagrammatically, with arrows drawn on. You can just about read the code
in the image too.
There are three modules: NFBT::ServerLib, NFBT::Utilities::Common and
NFBT::Utilities::Server. There is some requirement in them for
subroutines out of one or more of the others.
A small test program "trynfbt.pl" includes "shadow_conv" from
NFBT::Utilities::Server. The shadow_conv subroutine in
Utilities::Server imports a subroutine from ServerLib, which in turn
imports ":all: from Utilities::Common as well as the same shadow_conv
sub from Utilities::Server. (I hope you're following this). The last
piece of the jigsaw is that Utilities::Common imports XML::Twig::XPath.
Running the test program trynfbt.pl gives (These line numbers may not be
right because I knocked out blank lines and CR's to make the code
smaller to post)
"shadow_conv" is not exported by the NFBT::Utilities::Server module
Can't continue after import errors at
/usr/lib/perl5/site_perl/5.8.6/NFBT/ServerLib.pm line 28
BEGIN failed--compilation aborted at
/usr/lib/perl5/site_perl/5.8.6/NFBT/ServerLib.pm line 28.
Compilation failed in require at
/usr/lib/perl5/site_perl/5.8.6/NFBT/Utilities/Server.pm line 22.
... and three other lines that tell us no more.
But shadow_conv *is* exported, unless my brain is addled.
And removing any of the following lines makes the code run:
The import of Utilities::Common(':all')
The import of XML::Twig::XPath
.. and, of course, the other "use" statements.
Replacing XML::Twig::XPath with something else - I tried XML::Simple and
even File::Basename - also makes the code run clean; it has to be that
XML module despite the fact that it's never used. Eh?
Lastly here is the actual code from the three modules and the test
program. You might find the graphic easier ...
Test Program
============
#!/usr/bin/perl
use strict;
use warnings;
use NFBT::Utilities::Server qw ( shadow_conv );
print "This is the test routine $0\n";
The three modules
=================
------------------------------------------------------
package NFBT::ServerLib;
use 5.008;
use strict;
use warnings;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw(
write_xml_twig
) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'}}, qw(
write_xml_twig
) );
print "This is NFBT::ServerLib\n";
sub write_xml_twig {
# The original write_xml_twig required several subroutines from
# Utilities::Common and also 'shadow_conv'
# Comment either of these out, problem disappears
use NFBT::Utilities::Common ":all";
use NFBT::Utilities::Server qw(shadow_conv); # "not exported"
error here
print "This is write_xml_twig in package NFBT::ServerLib\n";
}
1;
--------------------------------------------------
package NFBT::Utilities::Common;
use 5.008;
use strict;
use warnings;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw(
find_bkfile_by_id
) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'}}, qw(
find_bkfile_by_id
) );
sub find_bkfile_by_id {
print "This is subroutine find_bkfile_by_id in package
NFBT::Utilities::Common\n";
use XML::Twig::XPath; # Comment this out, problem disappears. It
has to be
# XML::Twig::XPath, apparently. XML::Simple and File::Basename cause
the problem to
# disappear.
}
1;
------------------------------------------------------
package NFBT::Utilities::Server;
use 5.008;
use strict;
use warnings;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw(
shadow_conv
) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'}}, qw(
shadow_conv
) );
sub shadow_conv {
# The original shadow_conv used write_xml_twig
use NFBT::ServerLib qw(write_xml_twig); # Comment this out, problem
disappears
print "This is subroutine shadow_conv in package
NFBT::Utilities::Server\n";
}
1;
--
Henry Law Manchester, England