Perl - Subroutine redefined

32,956

Solution 1

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.

Solution 2

When you have two subroutines with the same name in different packages, you ought to see this warning (when warnings are enabled) as "Subroutine new redefined....". The simple reason (which is very close to what Grant McLean said, but still not exactly) is you must get your packages skip the compiling phase and make then require. This way, the Perl namespace manager will not find any such conflicting symbols with same name at compile time, and if you modules do not have any errors, they will work just fine afterwards also.

Just make sure you implement

require Module;

statement rather than

use Module;

You should not see this warning again.

Solution 3

If you're on a system with a case-insensitive filesystem (Windows, and quite often OSX), and you do use Common in one file and use common in another, you can cause problems like this.

Solution 4

This sounds like a problem caused by circular dependencies. Here is how to track it down. If your problem class looks like this:

package AlientPlanet;
use Dinosaurs;
sub has_dinosaurs {...}
1;

Then change your example to look like this:

package AlienPlanet;
sub has_dinosaurs {...}     # <-- swap
use Dinosaurs;              # <-- swap
1;

Now compile your code with Carp::Always like this:

⚡ perl -MCarp::Always -c lib/AlienPlanet.pm                                                                                                            
Subroutine has_dinosaurs redefined at lib/AlienPlanet.pm line 4.
    require AlienPlanet.pm called at lib/Dinosaurs.pm line 4
    Dinosaurs::BEGIN() called at lib/AlienPlanet.pm line 4
    eval {...} called at lib/AlienPlanet.pm line 4
    require Dinosaurs.pm called at lib/AlienPlanet.pm line 5
    AlienPlanet::BEGIN() called at lib/AlienPlanet.pm line 4
    eval {...} called at lib/AlienPlanet.pm line 4
lib/AlienPlanet.pm syntax OK

Now that you have a stacktrace you can see where the loop is. The quick and dirty solution is to use Class::Load in Dinosaurs.pm.

For a more detailed explanation try my blog post.

Solution 5

Are you by any chance running this as a cgi-script on a web-server?

I find I need to restart the webserver to get around this warning.

Share:
32,956
user210757
Author by

user210757

Updated on August 23, 2020

Comments

  • user210757
    user210757 over 3 years

    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?