Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: Sharing and over-riding package functions

by rir (Vicar)
on Dec 11, 2008 at 21:39 UTC ( [id://729782]=note: print w/replies, xml ) Need Help??


in reply to Sharing and over-riding package functions

I guess you want the writer of "Repl.pm" to be the arbiter of what happens:
package Orig; use Exporter; use vars qw( @ISA @EXPORT ); @EXPORT = qw( orig repl ); sub orig { print "&Orig::orig runs\n" } sub repl { print "&Orig::repl runs (O No!)\n" } 1;
package Repl; use warnings; use strict; BEGIN { use Orig; use Exporter; use vars qw( @ISA @EXPORT); @ISA = qq(Exporter); for ( @Orig::EXPORT) { no strict 'refs'; *{$_} = \&{"Orig::". $_}; } @EXPORT = ( qw( repl ), @Orig::EXPORT ); } no warnings 'redefine'; sub repl { print "&Repl::repl runs $/" } 1;
#!/usr/bin/perl # client program use warnings; use strict; use Repl; repl(); orig();
Output:
&Repl::repl runs &Orig::orig runs
Be well,
rir

Replies are listed 'Best First'.
Re^2: Sharing and over-riding package functions
by ruzam (Curate) on Dec 12, 2008 at 00:30 UTC

    Oh, you were so close! But I see now what I did wrong.

    Bringing the function refs from Orig into Repl is only part of the solution. But that still fails if one of the original functions calls another. Say orig() calls repl(). Even though orig() reference has been copied into package Repl and gets called from Repl, the orig() code still belongs to package Orig. When it executes, it will call Orig::repl() not the new Repl::repl() we just worked so hard to replace. I discovered this problem in my original post (after I posted of course).

    The other part of the solution is to replace the references in package Orig for any replaced functions in package Repl to ensure that when they get called, they execute the replaced function, not the original.

    # note: adjusted @EXPORT_OK in place of @EXPORT package Orig; use Exporter; use vars qw( @ISA @EXPORT_OK ); @ISA = qw(Exporter); @EXPORT_OK = qw( orig repl ); sub orig { print "&Orig::orig runs\n"; repl(); # this will not call the replaced repl() without help } sub repl { print "&Orig::repl runs (O No!)\n" } 1;
    package Repl; use warnings; use strict; # don't run in BEGIN blocks or we won't know what functions # we have defined use Orig; use Exporter; use vars qw( @ISA @EXPORT_OK); @ISA = qw(Exporter); for ( @Orig::EXPORT_OK) { no strict 'refs'; # check if we redefine this function # maybe it might not hurt to check for a function ref? if (${"Repl::"}{$_}) { # yes, save a SUPER:: copy so we can call it later *{"SUPER::" . $_} = \&{"Orig::". $_}; # now replace the original function with our new one no warnings 'redefine'; *{"Orig::" . $_} = \&$_; } else { # *{$_} = \&{"Orig::". $_}; } } @EXPORT_OK = ( qw( newfunc ), @Orig::EXPORT_OK ); # no warnings 'redefine' - not required here as we didn't import it; sub repl { print "&Repl::repl runs $/"; # finish with our original SUPER::repl(); } sub newfunc { print "&Repl::newfunc runs $/"; } 1;
      SUPER is a poor choice for a namespace because Perl defines SUPER to indicate a special pseudo-class. Your use of SUPER does coexist as a regular class of the same name. Confusing.

      See perldoc perlobj.

      Be well,
      rir

        SUPER is an excellent choice for a namespace (in this situation). It implies the same intention as Perl's built in pseudo-class, which is why I chose it. I get exactly what I expect by calling SUPER::myfunc(). Just as I get exactly what I expect by calling a blessed object with $obj->SUPER::myfunc().

        There would only be confusion if I were trying to mix a SUPER name space and blessed objects at the same time. If I had the option (or desire) to use blessed objects in this situation, I wouldn't need to mess with function references and namespaces :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://729782]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (4)
As of 2024-03-29 00:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found