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".