Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: A general method of locally overriding subroutines

by dragonchild (Archbishop)
on Mar 11, 2006 at 04:43 UTC ( #535874=note: print w/replies, xml ) Need Help??


in reply to A general method of locally overriding subroutines

sub localize { my $real = pop; no strict 'refs'; AGAIN: local *{shift@_} = sub { 'changed' }; goto AGAIN if @_; $real->(); }
One of the few places that goto LABEL is useful.

My criteria for good software:
  1. Does it work?
  2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

Replies are listed 'Best First'.
Re^2: A general method of locally overriding subroutines
by tmoertel (Chaplain) on Mar 11, 2006 at 05:33 UTC
    Clever. It just needs one more goto to handle the empty case (no overrides) gracefully:
    sub localize { my $real = pop; no strict 'refs'; goto CALL unless @_; AGAIN: local *{shift@_} = sub { 'changed' }; goto AGAIN if @_; CALL: $real->(); }
    Even so, it's easier to understand than the nested-subroutines solution.

    I wonder if anybody out there has got something even simpler.

      Simpler, or did I miss something?

      #! perl -slw use strict; $, = ' '; sub a{ 'a' } sub b{ 'b' } sub c{ 'c' } sub d{ ( a, b, c ) }; sub localize { no strict 'refs'; no warnings 'redefine'; A: local *{ +shift } = sub{ 'changed' }; goto A if @_ > 1; +shift->(); } print d; print localize qw[a b c], \&d; print d; print localize qw[a c], \&d; print d; __END__ C:\test>junk a b c changed changed changed a b c changed b changed a b c

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
      Even so, it's easier to understand than the nested-subroutines solution.

      More importantly, the stackdump is more easily understood.

      I wonder if anybody out there has got something even simpler.

      I would hope there's something better than that. For one thing, my version doesn't allow each function to be a closure. Though, that's easy enough to fix, I suppose.

      sub localize { my $real = pop; no strict 'refs'; no warnings 'redefine'; goto CALL unless @_; AGAIN: my $v = shift; local *{$v} = do { my $v2 = $v; sub { "changed $v2" } }; goto AGAIN if @_; CALL: $real->(); }

      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (2)
As of 2020-10-25 03:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (248 votes). Check out past polls.

    Notices?