jeanluca has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks

I have two packages when used in the same program give me the following warning:
Subroutine xyz redefined at ../A.pm ....
My code looks like:
use A ; use B ; .... do something
In A.pm I see a subroutine xyz but not in B.pm. But B.pm uses many other packages, which can include A.pm. But still, how can any of this give me this warning ?

Furhtermore, I tried to fix this using eval
use A ; eval { use B ; # do stuff which only requires B } # do stuff which only requires A
which, unfortunately, didn't solve it (same result). Is there an easy fix for this ?
cheers
LuCa

Replies are listed 'Best First'.
Re: subroutine xyz redefined at ...
by kennethk (Abbot) on Aug 24, 2009 at 16:06 UTC
    There is a point which you need to clarify: is the warning the issue you wish to fix, or is perl invoking the wrong version of xyz? Obviously, the latter is a serious issue since you are getting incorrect behavior. However, if the issue is simply the warning, this is certainly an appropriate time to suppress the warning. Warnings pop-up when you do something that is potentially but not necessarily problematic. In this case, both A and B export a subroutine xyz and you know it, so the warning has served its purpose. In this case, try the code:

    use A ; eval { no warnings 'redefine'; use B ; # do stuff which only requires B } # do stuff which only requires A

    Alternatively, you could modify your import behavior. If A.pm and B.pm are in-house, consider modifying them to use EXPORT_OK in place of EXPORT - see Exporter

Re: subroutine xyz redefined at ...
by ikegami (Patriarch) on Aug 24, 2009 at 16:10 UTC
    Do "A" and "B" both have a package statement? Do either export "xyz"?
Re: subroutine xyz redefined at ...
by jeanluca (Deacon) on Aug 24, 2009 at 16:50 UTC
    let me clarify:

    I found out that there is a CPAN version of A.pm, which is used by the base package of B.pm
    I guess loading two different packages with the same package-name give me this warning!

    So, the questions is, can this be solved ? I get the impression that eval doesn't do this!

    I can of course do:
    use A ; my $result = `doSomething.pl` ; # doSomething.pl uses B.pm ....
      So when B.pm loads A.pm, it overwrites everything that A.pm already put in the symbol table, and you get your error. Given that you can isolate code that uses A.pm explicitly from that which uses B.pm and success loading B.pm implies A.pm will load successfully, I think the simplest answer is to isolate the blocks of code from each other. For example:

      { use B ; # do stuff which only requires B } { use A; # do stuff which only requires A }
        testing your solution gives me the exact same warning!

        UPDATE: Also, the use statements are executed when the program starts, so the blocks around it do not influence which module is used. Depending on which is processed last, is used!
Re: subroutine xyz redefined at ...
by Anonymous Monk on Aug 25, 2009 at 00:25 UTC
    You are aware that B is a core module ?
      Now that you mention it, yes. But A.pm stands for some other module name (same for B.pm)!