Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: Exported subroutine redefine

by Somni (Friar)
on Nov 10, 2007 at 12:35 UTC ( [id://650050]=note: print w/replies, xml ) Need Help??


in reply to Exported subroutine redefine

Short of reaching into the package that imported the subroutine, I'm not seeing a way.

You could crawl all over the symbol table finding any references to the old Foo::foo and update them. You're already doing something horribly icky, what's a bit more eh?

Edit: Hah, I meant module::function, sorry. Foo::foo was the name of the function I was using to test things.

Replies are listed 'Best First'.
Re^2: Exported subroutine redefine
by ribasushi (Pilgrim) on Nov 10, 2007 at 19:17 UTC
    Thanks for answering, this sounds like a good idea. Can you tell me how can I get a list of all currently populated namespaces? %INC contains only namespaces tied to a physical .pm file, and if a file has several package X pragmas I will examine only the first one.

    Btw if you are curious the ickyness comes form the fact that I am fooling around with exception handling, and I had this nice idea of globally redefining Carp::croak() and Carp::confess() to throw an object except of a string (I know I know it is far from best practice to fool around with core modules, but I really liked the idea, an wanted to see if it can actually work). Since Carp is a very central module it is being used all over the place in many other modules, and hence it is
    1) impractical to change all calls to it Carp::x()
    2) impractical to attempt to load my exception handler before any references to Carp.
    The two subroutines that must be redefined are trivial one-liners, thus I figured it should do no harm:
    sub croak { die shortmess @_ } sub confess { die longmess @_ }


    Addition: Why I don't simply overload CORE::die? Because for one it can be overloaded by someone else, and more importantly module authors sometimes examine $@ and finding an object there has a very remote chance of breaking stuff (although I have backwards compatible stringification of '<error> at <file> line <ln>.' On the other hand croak is clearly designed to be seen by the user, who in this case will be expecting an object.
      In the case of Carp specifically there is a far easier way. Use Carp::Heavy. Then redefine Carp::longmess_heavy and Carp::shortmess_heavy.

      Otherwise you'd have to walk the symbol table. Just to get you started on that, print out the keys of %main::. All of the keys ending in :: are subtables you can look for. Beware of infinite loops. (For instance %main::main::main:: is the same as %main::.)

      Strange, why aren't you just setting up your own $SIG{__DIE__} handler? It seems tailor-made to solve your problem for you. Granted, it's a hack, and can get messy, but it's a far better hack than trying to overload another module's subroutines globally.

      A long time back I went down this road, as well. I thought it was a great idea to setup a __DIE__ handler and catch all the errors, turning them into pretty output for a web framework I was designing. I suppose it worked, sorta. It's much cleaner to design an actual exception model, with exception classes thrown by code, and possibly a catch routine that can transform string exceptions into a relevant object.

      If the object in $@ has stringification it shouldn't break anything that's attempting to match against it. The only thing it should "break" is something that's checking to see if it's an object, in which case that code should know what it's doing.

        Because $SIG{__DIE__} is too often used by other packages as well. I think my final solution is cleaner in regards to what I want to do.
      Could you just redefine Carp::shortmess and Carp::longmess? If not, you can walk the symbol table starting with something like this:
      for (grep /(?<!main)::/, keys %::) { # do stuff... }

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (1)
As of 2024-04-19 00:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found