Object::Deadly kills buggy diagnostics

jjore on 2006-08-15T18:53:26

I wrote Object::Deadly because I was tired of diagnostic modules forgetting to watch for overloaded objects. It'd be nice for it to use Carp::Clan but C::Clan suffers from the same bug O::Deadly is meant to help test for!

http://rt.cpan.org//Ticket/Display.html?id=21002> contains a patch to bring Carp::Clan 5.3 up to 5.4 which *is* smart about overloading. I also wrote some tests for C::Clan that use O::Deadly because that's exactly what it's there for.
I'm amused by this - just getting O::Deadly off the ground required patching some of it's infrastructure.

Oh yes, infrastructure? I have a rant coming about the evil, evil, evil UNIVERSAL::require module.


UNIVERSAL::require

Ovid on 2006-08-15T19:07:00

The only serious problem I see with UNIVERSAL::require is that people need to learn that if they use this module, they need to be careful if they have methods named require or use. As a general rule, it's a bad idea to use keywords as method names (though I've done this when it was appropriate). On the other hand, people use methods (even functions!) named isa, can and version incorrectly, so I can't expect them to play nicely with code.

The only reason I submitted a patch to that module is that I'm seeing this showing up in code where people aren't checking the return value. If they don't check the return value, then eval { "require $module" } is likely to suffer the same fate. That's bad programmers, not bad programming.

Re:UNIVERSAL::require

jjore on 2006-08-15T19:18:42

Inserting things in UNVERSAL that aren't already there causes *every* object and class everywhere to have to potentially know about it. I used Devel::Symdump to get the list of all the currently known functions in UNIVERSAL so I could know that all method calls made on my object were going to be handled within my object.



This is an impossible task as long as people keep polluting UNIVERSAL. Say someone loads my module, then loads something else which pollutes. It's now possible for someone to use that inserted method on my object and that is not ok.

use Object::Deadly;
*UNIVERSAL::argh = sub { 'Ha ha!' };
 
my $obj = Object::Deadly->new;
 
# Calls UNIVERSAL::argh, not Object::Deadly::AUTOLOAD.
$obj->argh;

So the fact that people are using UNIVERSAL::require (or anything UNIVERSALy polluting) requires me to maintain a list or something of all polluters and manually account for them.



So it's just bad. It shouldn't have been written and no one should have ever used it. I read that Jifty uses it so I suppose Jifty should be patched to *not* use it ASAP. *grumble* UNIVERSAL::require could have been written as a plain function without the pollution but I guess that just wasn't cute enough or something. I don't think there's any excuse for it.

Re:UNIVERSAL::require

jjore on 2006-08-15T19:21:46

I suppose I'd like to add that I didn't even realize I had this problem with UNIVERSAL::require when I was complaining about it to you the other day. Yesterday it was just angst over ETOOMUCHMAGIC. Today it's a gripe that it actually breaks stuff when it loads.

Re:UNIVERSAL::require

kane on 2006-08-16T09:07:16

On a side note, there's also Module::Load which fixes the same problem UNIVERSAL::require is addressing, whithout polluting UNIVERSAL::*.

On the upside, it's even core as of 5.9.4

Re:UNIVERSAL::require

jjore on 2006-08-16T13:39:31

Cheer! Cheer! Huzzah!

"Fixing" UNIVERSAL pollution in a class means reading the source code for all the modules on CPAN that are likely to touch UNIVERSAL. Ugh. Did that yesterday. I'm considering putting up some kind of notification service to myself to watch for the next UNIVERAL polluting module.

****UGGGLLLYYY!!!