Perl - Subroutine redefined

user210757 picture user210757 · Aug 7, 2010 · Viewed 31.1k times · Source

I have asked this question before or searched and seen others ask - why am I getting the warning "Subroutine mySub redefined at ../lib/Common.pm line x"? and you always get the answer you declared the sub twice in the same code. I created this test package:

ENTIRE FILE ---------------

package MyCommonPkg;

use strict;

sub thisSubroutineIsNotDefinedAnywhereElse{
}

1;

ENTIRE FILE ---------------

and I USE this package from a perl script, which uses other packages, that use this package also, and I get the warning:

Subroutine ThisSubroutineIsNotDefinedAnywhereElse redefined at ../lib/MyCommonPkg.pm line 19.

I promise I did not declare this sub anywhere else. So is this caused by a circular reference? How can I go about tracking the cause of this warning down and fixing?

Answer

Grant McLean picture Grant McLean · Aug 7, 2010

Do you have a dependency loop? If Perl starts compiling your script and encounters a line like this:

use PackageA;

Perl pauses the compilation of your script; locates PackageA.pm and starts compiling it. If it encounters a line like this:

use PackageB;

Perl pauses the compilation of PackageA; locates PackageB.pm and starts compiling it. Normally, that would complete successfully, and Perl would go back to complete compiling PackageA and when that completes successfully it would go back to compiling your script and when that completes successfully it would start to execute the compiled opcodes.

However, if PackageB.pm contains this line:

use PackageA;

You might expect it would do nothing since Perl has already processed PackageA.pm but the problem is that it hasn't finished yet. So Perl will pause the compilation of PackageB and start compiling PackageA.pm again from the beginning. That could trigger the message you're seeing about subroutines in PackageA being redefined.

As a general rule, two packages should not both depend on each other. Sometimes however the loop is harder to locate because it is caused by a third package.