On Tuesday 27 February 2007 00:13, Michael G Schwern wrote:

> If that were so it would only warn when a MockObject is looked at using
> UNIVERSAL::isa/can() as a function. 

You really ought to read the code, especially the part where Test::MockObject 
and UNIVERSAL::isa and UNIVERSAL::can are separate modules.

The previous paragraph is brought to you by the word "decoupled" and the 
letters Q and A.

> That would cover the utility of 
> warning a user about a possible problem using mocked objects without
> launching a UNIVERSAL::isa crusade.  As it is it warns on *any* use of
> UNIVERSAL::isa() as a function, mocked object or no (although right now
> UNIVERSAL::isa appears to not warn at all).

Yes, that's what UNIVERSAL::isa and UNIVERSAL::can do.  They attempt to work 
around the damage of using base methods as functions and warn about them.

Test::MockObject and Test::MockObject::Extends use both other modules because 
that anti-pattern tends to break mock objects.

It tends to break other types of code too, which is why they are separate 
modules.

The previous three paragraphs are brought to you by the words "modularity" 
and "generalization" and the letters O, O, and P.

> When I'm programming on a project I want to work on that project.  What I
> do *not* want to do is have something totally unrelated nagging me to fix
> potential bugs in someone else's code.

When I'm programming on a project, I want the rest of the code to work and not 
generate strange failures.

> Instead, a course of eduction and contacting the actual authors of the
> naughty code is in order.  You've certainly started in on the former.  As
> for the latter, I suggest doing a Google Perl code search for "UNIVERSAL::"
> and contacting each of the authors.

That didn't work.

Chris Dolan, I believe, had an interesting conversation with Andy Wardley over 
strange Template Toolkit failures with Test::MockObject.  I believe this was 
also pre-UNIVERSAL::isa.

Even Ben Tilly, dispenser of voluminous wisdom on Perl Monks, still seems to 
believe that can() is a method not worth supporting because "some people 
might not use it correctly".

> Now for the analysis why putting crusader code into otherwise functional
> modules is a bad idea:
>
> _Modules are supposed to be modular_  They should avoid universal effects
> or poking around in other namespaces without a damned good reason.  If I
> download a module which does X I do not want it to also launch a Crusade
> against other installed code.  Stay in your box.

UNIVERSAL::isa and UNIVERSAL::can are separate modules.  They don't know the 
internals of Test::MockObject nor any other code that might want to use them.  
This is on purpose.

> _You're alerting the wrong person_  If there's a problem with a CPAN module
> the author of that module should be told, not the users.

The users are the ones who will encounter the bugs when, as just one example, 
Test::MockObject falls prey to someone else's buggy code.

> _You're annoying the user_  By adding on Crusader Code to a module you're
> causing annoyance to the users of your module who, as mentioned above,
> often can't do much about it.

They can report the bug, much as they would have to do if they encountered it 
in practice.  However:

1) UNIVERSAL::isa and UNIVERSAL::can work around the bug
2) The warnings are merely warnings, not crashings and errors, as the bug 
would be
3) The warnings do their best to identify exactly *where* the bug is, which 
beats trying to figure out weird crashes all to pieces

> _You're annoying LOTS of users_  The solution to any particular mistaken
> use of UNIVERSAL::isa in a CPAN module is for the author to patch it. 
> Maybe one user reports the bug and provides a patch.  One user, one bug
> report, one patch, one author.  In order to effect this change you are
> spewing warnings at lots and lots of people, many of which can do nothing
> but report the bug.

Yet these bugs aren't getting fixed.

It seems to me that there's a different problem somewhere else.

Exactly how long have we been talking about UNIVERSAL::isa and UNIVERSAL::can 
*not* being functions?  Years!

Years!!

If I thought evangelism alone would work, I'd stick to that.

If I thought piling workaround upon workaround would work, I'd do that too, 
but I'm not a PHP programmer with a security hole.

> _You're conflating two behaviors into one module_ 

Again, you really ought to read the code.

> I want to use 
> Test::MockObject to mock objects.  Scanning my code for mistaken uses of
> UNIVERSAL::isa is another thing entirely that I may or may not want to do.
> By bolting the two together it becomes impossible to do one without the
> other.  This lowers the utility of MockObject.

Yeah, it really SUCKS that Test::MockObject has a chance of working despite 
bugs in other people's software.  The refund line is ---> over there, right 
under the "You're WELCOME!" sign.

> _You can break other people's code_  By mucking with other people's code
> you potentially *break* that code.  By *silently* changing the way isa()
> works

I thought the problem was that it warned.  This is a new definition of the 
word silent.

> , or in Eric's case deleting a $SIG{__DIE__} handler, any mistake you 
> make can now break lots of other totally unrelated code.

Yeah, bad programming can break unrelated code, such as Test::MockObject.  
This is, to me, not news.

> As UNIVERSAL::isa and can have had and currently do have bugs (I can't even
> get UNIVERSAL::isa to warn)

RT is also ---> over there.

I thought test suites were in place to help preserve and identify quality.  If 
you have a problem with your test suite, that should identify a quality 
problem.  If you're using code that has a severe confusion about the 
difference between methods and functions, you have a quality problem.

The connection, to me, is fairly direct.

-- c

Reply via email to