http://www.perlmonks.org?node_id=473812


in reply to Test::MockObject doesn't fool UNIVERSAL

Well, the problem is that there is a difference between:
$x->method(...)
and
class::method($x, ...)
even if "class" is the class in which $x is blessed, or one of the ancestors of that class. When you say $x->method(...), you are invoking what's called "method dispatch", a (breadth-first) search for a method in the class in which the object is blessed and its ancestors. When you say class::method($x, ...) (basically equivalent to $x->class::method(...)), you are foregoing the search and telling perl which class's method to use.

Now, in this example, you are going straight to UNIVERSAL for its can and isa methods, rather than allowing method dispatch to find the can and isa methods in the (nearer than UNIVERSAL) ancestors of your class (or the class itself). Thus, what you're getting is UNIVERSAL::can, rather than Class::MockObject::can (which is what the method dispatch would have found).

The last thing, though, is that perl almost forces you to do this. If you've got an object, and you don't know what it is, then calling $x->can('foo') could be a really bad idea. Well, that's not true... if you know that $x is, in fact, an "object" then you're cool. The problem is: what if you don't know whether $x is an object (a blessed reference), or if it's just a plain, unblessed reference, or not even a reference at all. Then, if it *can* foo, then it'll return true, but if it *cannot* foo, then it might die! Anyway, the UNIVERSAL::can and UNIVERSAL::isa CPAN modules mentioned by itub are pretty cool and basically deal with this, in a way (but they warn if you do it).

------------ :Wq Not an editor command: Wq