cmp_ok() is changing, with regard to overloaded objects, to be as close to the 
behavior of the actual comparison as I can get it.  is() and is_deeply() will 
remain the same as they have a fuzzier idea of equality.  I'm still working on 
the implementation.


As of 0.60_01 cmp_ok() has "unoverloaded" any objects before comparison by 
using their 0+ or "" ops as appropriate for the comparison op.  I had changed 
is() and is_deeply() to work on overloaded objects which did not overload 
comparison but did overload 0+ and/or "" and figured it would be a good idea of 
cmp_ok() was smart.

As is often the case when software tries to be smart, its screwed things up.

Sometimes objects only overload the comparison ops and not the "ifys" [1]  
DateTime, for example, overrides comparison and stringification but not numify 
because there's no general way to convert a date into a number.  This causes 
problems with cmp_ok.

$ perl -MDateTime -wle 'print DateTime->now == DateTime->now'
1

$ perl -MDateTime -wle 'use Test::More tests => 1;  cmp_ok( DateTime->now, 
"==", DateTime->now )'
1..1
Cannot add 0 to a DateTime object (DateTime=HASH(0x180124c)).
 Only a DateTime::Duration object can  be added to a DateTime object. at 
/usr/local/perl/5.8.8/lib/Test/Builder.pm line 513

It should work, but cmp_ok() gets confused because its trying to get the 
numeric value of the object.  (That's actually my dualvar() detection going 
bad, but you get the idea.)  So that's one case where cmp_ok() diverges from 
reality.

Another case is when a class has overloaded the ifys but not the comparision 
ops and fallback is not on.

$ perl -wle 'package Foo;  use overload q[""] => sub { return $_[0]->[0] };   
$o = bless ["thing"], "Foo";  print $o eq "thing";'Operation "eq": no method 
found,
        left argument in overloaded package Foo,
        right argument has no overloaded magic at -e line 1.

$ perl -wle 'package Foo;  use overload q[""] => sub { return $_[0]->[0] };   
$o = bless ["thing"], "Foo";  use Test::More tests => 1;  cmp_ok $o, "eq", 
"thing";'
1..1
ok 1

Normally the comparison fails, but cmp_ok() tries to be helpful and makes it 
work.  That's wrong.  The point of cmp_ok() is to know exactly what sort of 
comparison is being done.  is() does the fuzzy stuff.



[1] My term for 0+ and "".  "numify" and "stringify".

Reply via email to