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

I have a perl script which imports the same function from two different modules. I want to be able to call both of these functions one after the other. The following are the code snippets including the output. Please advise on any ideas. Thanks.
---------------------------
# runscript.pl

use AB qw( testing );
use CD qw( testing );

testing();


----------------------------
package AB;

our (@ISA, @EXPORT);
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw( testing );

sub testing {
print "Package AB\n";
return;
}

1;

-----------------------------
package CD;

our (@ISA, @EXPORT);
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw( testing );

sub testing {
print "Package CD\n";
return;
}

1;

------------------------------
> perl runscript.pl

Current output:
> Package CD

Expected output:
> Package AB
Package CD

Replies are listed 'Best First'.
Re: Recursive use statements?
by jethro (Monsignor) on Jul 20, 2011 at 23:35 UTC

    You can always call subroutines in other modules like this:"CD::testing(); AB::testing();". So calling them is easy

    I assume that importing two functions with the same name also produces warnings. If you want to avoid these, you could change your modules to only export on request, i.e. instead of @EXPORT use @EXPORT_OK in the module and if you want to import a subroutine into your namespace, use "use AB(testing);".

    Or you call a module like this: "use AB()"; In this case no names are imported at all, even when they are in your @EXPORT array.

      Considering the OP is using use AB qw[testing], it doesn't matter at all whether AB is using @EXPORT or @EXPORT_OK. That difference plays only a role if a use statement without parameter is used.
Re: Recursive use statements?
by davido (Cardinal) on Jul 21, 2011 at 00:37 UTC

    If you want to get your hands dirty you can manipulate package main::'s symbol table. Below you'll see a number of examples of how to either manipulate your local symbol table, or access a function in another package without importing it or aliasing the symbols.

    package AB; sub testing { print $_[0] . ": " . __PACKAGE__ . "\n"; } 1; package CD; sub testing { print $_[0] . ": " . __PACKAGE__ . "\n"; } 1; package main; use strict; use warnings; use 5.014; my $count = 0; foreach ( qw/ AB CD/ ) { no strict 'refs'; &{$_ . '::testing'}($count++); } *testing = \&AB::testing; # redefined warning testing($count++); *testing = \&CD::testing; # redefined warning testing($count++); $::{testing} = \&AB::testing; # redefined warning testing($count++); $main::{testing} = \&CD::testing; # redefined warning testing($count++); $main::{testing} = *AB::testing{CODE}; # redefined warning testing($count++); *testing = *CD::testing; testing($count++); *main::testing = *AB::testing; testing($count++); $main::{testing}= *CD::testing; testing($count++); foreach( qw/AB CD/ ) { no strict 'refs'; *main::testing = *{ $_ . "::testing" }; testing($count++); }

    Not all of the above methods accomplish the same exact thing. Some alias an entire typeglob (an entire symbol). Others select only the subroutine for aliasing (leaving other "THING"s in the typeglob untouched. And some simply invoke the sub by fully qualifying its originally package name. I included a bunch of examples just to show some of the ways.

    Note: Whenever Perl knows that you're specifically overwriting an existing declaration of a sub it will issue a warning. Typeglob to typeglob aliasing subverts that warning, but coderef to typeglob assignments do not subvert the warning. Consider it a feature, that Perl will complain to you when you do something silly if it sees you doing it.

    One of the issues you face when using 'use' is that any subsequent 'use' that exports the same subroutine will mask the previous one. This is where carefully chosen exports is important, as well as knowing how to get at the fully qualified name.


    Dave

Re: Recursive use statements?
by ikegami (Patriarch) on Jul 21, 2011 at 00:41 UTC

    If testing was a method rather than a function, then I'd suggest roles and Moose's around. But it's not, so you're left with

    use AB qw( ); use CD qw( ); sub testing { AB::testing(); CD::testing(); }

    It's a big hindrance that we have no idea what you are really ("big picture") trying to do.

Re: Recursive use statements?
by ikegami (Patriarch) on Jul 21, 2011 at 00:38 UTC
Re: Recursive use statements?
by Anonymous Monk on Jul 21, 2011 at 00:17 UTC
Re: Recursive use statements?
by locked_user sundialsvc4 (Abbot) on Jul 21, 2011 at 15:01 UTC

    Also remember that use is basically a declaration, not a “statement.”   Similar to yet different from require, it changes the Perl execution environment.   The term, “recursive,” does not (AFAIK) meaningfully apply to what it does.