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

I have an application which uses interchangeable backends. For normal use you have to pick one, since they each define the same subs in the same package that do different things.

During testing I usually start with a single test file, which tries to use all the modules. But, when I do that for this project, I get subroutine redefinition warnings. As you can see below, I tried some variations of no warnings without much luck. Is there a way to suppress these, or do I have to use separate test files?

Here are some of my attempts (all of them led directly to redefined warnings):

use Test::More tests => 2; no warnings; BEGIN { use_ok( 'Backend::A' ); } BEGIN { use_ok( 'Backend::B' ); }

use Test::More tests => 2; no warnings qw( redefine ); BEGIN { use_ok( 'Backend::A' ); } BEGIN { use_ok( 'Backend::B' ); }

use Test::More tests => 2; BEGIN { use_ok( 'Backend::A' ); } BEGIN { no warnings qw( redefine ); use_ok( 'Backend::B' ); }

# having given up on testing temporarily: no warnings qw( redefine ); require Backend::A; require Backend::B;
Phil

Replies are listed 'Best First'.
Re: Suppressing Subroutine redefined warning
by jdporter (Paladin) on Mar 27, 2006 at 20:07 UTC

    How are they defining the same subroutines? Are they defining subs in the same namespace, e.g. main? If so, that's probably not a good idea. If possible, you should have each package define the subs in its own namespace, and then use a classname to access the subs in one namespace or the other. Like so:

    # Backend::A package Backend::A; sub foo { } 1;
    # Backend::B package Backend::B; sub foo { } 1;
    # main my $backend = 'Backend::A'; require $backend; $backend->foo(); # then later, if necessary: $backend = 'Backend::B'; require $backend; $backend->foo();
    We're building the house of the future together.
      They are mixins which define subs in the same packages, but not main. I agree that that would be a bad idea.

      It's possible I could be talked out of my mixin scheme, but it would take you a lot of effort. Explaining why would also be a lot of effort, which I will avoid, at least for now.

      Phil

        The warnings pragma is lexical. If you don't want the 'redefine' warnings, you have to say so in the mixin classes themselves.

        Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
        How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: Suppressing Subroutine redefined warning
by chromatic (Archbishop) on Mar 28, 2006 at 01:49 UTC

    Set a warning handler in %SIG:

    $SIG{__WARN__} = sub { my $warning = shift; warn $warning unless $warning =~ /Subroutine .* redefined at/; };