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

I have an exported function. In this function, there's a call to another function (which is not exported). This other function resides in the program that uses the exported function. However there is also a function with the same name in the module that exports the function. How do I make the exported function call the right function (the one in the caller's namespace)?

Here's an example of what I am talking about:

package TT; use Exporter; @ISA = qw/Exporter/; @EXPORT = qw/s1/; sub s1 { print "s1"; s2(); } sub s2 { print "s2"; } 1; perl -wle 'use TT; sub s2 { print "NO S2!"; } s1();' output: s1 s2 I want: s1 NO S2! ?

Replies are listed 'Best First'.
Re: Calling functions from different namespaces
by Madcap Laughs (Acolyte) on Jan 18, 2006 at 02:23 UTC
    Well ... the way you've coded things, TT::s1() calls TT::s2(). If you don't want TT::s2() to be called then you need to either:
    a) not call TT::s1(), or;
    b) rewrite TT::s1() in such a way that it accommodates the possible existence of main::s2() - for example (in TT.pm):
    sub s1 { print "s1"; if(defined(&main::s2)) {main::s2()} else {s2()} }
    See perldoc -f defined

    Cheers,
    Rob
Re: Calling functions from different namespaces
by ikegami (Patriarch) on Jan 18, 2006 at 06:03 UTC

    If I were to guess, I'd say you were trying to override "s2" in some existing package, without modifying the module. If that's indeed what you are trying to do, then the best you could do would be to replace "s2" entirely:

    perl -wle 'use TT; sub TT::s2 { print "NO S2!"; } s1();'

    To avoid the warning:

    perl -wle 'use TT; BEGIN { undef *TT::s2; } sub TT::s2 { print "NO S2! +"; } s1();'
      Couldn't I also use a coderef in the arguments to s1? For example:
      s1(\&s2)
      Someone suggested this approach to me, but I don't know how to flesh the rest of it out... I would have to alter s1 to read in the coderef. How could I do that? thanks
        sub s1 { my $sub=shift; # get it! # you may want to add checks => perldoc -f ref. print "s1"; $sub->(); # execute it! }

        Indeed they gave you a good suggestion: this is the best way to do what you say you want to do.