Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Journal of jjore (6662)

Friday December 22, 2006
05:09 PM

Just wrap PL_ppaddr[OP_REF]!

[ #31991 ]

Jifty's land grab on the '0' package is irksome. There's only one other similar package and that's "\0" and it's impossible(?) to install methods into. The real problem is that some objects would prefer to be thought of as "not an object" and bad code out there uses ref() to decide this.

I figure it'd be better to be able to have a general mechanism where ref() can return false for any given object should that behaviour be desired.

I initially thought of installing &ref to override the builtin. This works as long as you do it before your calling code is compiled but not after. Oops.

Instead of that, the opcode pp_ref itself can be overridden by swapping in our own function into PL_ppaddr[OP_REF]. Woot! That'd work and this would mean objects of *any* class can request funky behaviour for ref( $obj ).

Cool. Package 0 isn't needed anymore (only if this wrapper gets written).

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • One potential drawback is that you'd have to swap in a different function pointer before Perl constructs the optree of the calling code. Of course, a little B::Deparse and PadWalker magic can fix that, if you don't mind recompiling a few bad calls.

    That where it seems to me much easier to rap the knuckles of every chucklehead who thinks that ref() gives useful answers in Perl. (Note to potential non-chuckleheads: it doesn't. Get over it.)

    • Oh...

      I thought of PL_ppaddr[...] as a global dispatch table but I guess that's wrong. I just learned that every op has the proper function pointer copied into it in the op_ppaddr. So to override ref() I'd actually need to find all the opnodes that have pointers to the real(?) function and swap in my own.


      Is there a reason for this? This means two "equivalent" opnodes can have different op_ppaddrs. That's an interesting feature and I've never heard of anyone that for anything. Possibly lexically different
      • I've used it productively, but that code's not suitable for general use yet.

        To my best guess, with no specific knowledge, it's there to make op dispatch in the runloop as fast as possible; it's a nice, simple scheme there.

        • This strikes me as an interesting way to instrument code for debugging. The edebug in emacs does something where it wraps every instruction in a function for execution. Something similar could happen in perl 5.
  • Jifty uses Scalar::Defer. Scalar::Defer does magic with '0'