views:

117

answers:

2

I have a Perl module that appears to compile fine by itself, but is causing other programs to fail compilation when it is included:

me@host:~/code $ perl -c -Imodules modules/Rebat/Store.pm
modules/Rebat/Store.pm syntax OK
me@host:~/code $ perl -c -Imodules bin/rebat-report-status
Attempt to reload Rebat/Store.pm aborted
Compilation failed in require at bin/rebat-report-status line 4.
BEGIN failed--compilation aborted at bin/rebat-report-status line 4.

The first few lines of rebat-report-status are

...
3 use Rebat;
4 use Rebat::Store;
5 use strict;
...
+5  A: 

Edit (for posterity): Another reason for this to occur, and perhaps the most common reason, is that there is a circular dependency among the modules you are using.


Look in Rebat/Store.pm for clues. Your log says attempt to reload was aborted. Maybe Rebat already imports Rebat::Store, and Rebat::Store has some package-scope check against being loaded twice.

This code demonstrates the kind of situation I mean:

# m1.pl:
use M1;
use M1::M2;
M1::M2::x();

# M1.pm 
package M1;
use M1::M2;
1;

# M1/M2.pm
package M1::M2;
our $imported = 0;
sub import {
    die "Attempt to reload M1::M2 aborted.\n" if $imported++;
}
sub x { print "42\n" }
1;

$ perl m1.pl
Attempt to reload M1::M2 aborted.
BEGIN failed--compilation aborted at m1.pl line 3.

The code will compile (and print 42) if you just remove the use M1::M2 line in m1.pl. In your case, you might not need to explicitly use Rebat::Store in your program.

mobrule
The problem was, in fact, due to a newly introduced circular dependency between Rebat.pm and Rebat/Store.pm
chrisribe
+1  A: 

perldoc perldiag:

 Attempt to reload %s aborted.
           (F) You tried to load a file with "use" or "require" that failed to
           compile once already.  Perl will not try to compile this file again
           unless you delete its entry from %INC.  See "require" in perlfunc
           and "%INC" in perlvar.
eugene y