http://qs321.pair.com?node_id=11144043

syphilis has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

Have a laugh at this piece of brilliance:
C:\>perl -MMath::MPFR -MTest::More -e "cmp_ok(Math::MPFR->new(2), '!=' +, Math::MPFR->new(2), 'test for blow up'); done_testing();" not ok 1 - test for blow up # Failed test 'test for blow up' # at -e line 1. Operation "eq": no method found, left argument in overloaded package Math::MPFR, right argument in overloaded package Math::MPFR at C:/perl-5.3 +4.0/site/lib/Test/Builder.pm line 1006. A context appears to have been destroyed without first calling release +(). Based on $@ it does not look like an exception was thrown (this is not + always a reliable test) This is a problem because the global error variables ($!, $@, and $?) +will not be restored. In addition some release callbacks will not work prop +erly from inside a DESTROY method. Here are the context creation details, just in case a tool forgot to c +all release(): File: -e Line: 1 Tool: Test::More::cmp_ok Here is a trace to the code that caused the context to be destroyed, t +his could be an exit(), a goto, or simply the end of a scope: Context destroyed at C:/perl-5.34.0/site/lib/Test/Builder.pm line 1006 +. eval {...} called at C:/perl-5.34.0/site/lib/Test/Builder.pm l +ine 1006 Test::Builder::cmp_ok(Test::Builder=HASH(0x24eaa60), Math::MPF +R=SCALAR(0x86b998), "!=", Math::MPFR=SCALAR(0x33cf88), "test for blow + up") called at C:/perl-5.34.0/site/lib/Test/More.pm line 511 Test::More::cmp_ok(Math::MPFR=SCALAR(0x86b998), "!=", Math::MP +FR=SCALAR(0x33cf88), "test for blow up") called at -e line 1 Cleaning up the CONTEXT stack... # Tests were run but no plan was declared and done_testing() was not s +een. # Looks like your test exited with 255 just after 1.
Note that the problem arises at C:/perl-5.34.0/site/lib/Test/Builder.pm line 1006.
It's not the test failure that's an issue - pretty obviously, that test should fail.
It's the ensuing fatal over-the-top blowup that's my main concern.
Here's the actual section of the Test::Builder code that blows up:
... unless($ok) { $self->$unoverload( \$got, \$expect ); if( $type =~ /^(eq|==)$/ ) { $self->_is_diag( $got, $type, $expect ); } elsif( $type =~ /^(ne|!=)$/ ) { no warnings; my $eq = ($got eq $expect || $got == $expect) ## LINE 1006 ...
The evaluation of $got eq $expect is bound to be interesting if $got is an object and the 'eq' operator has not been overloaded

Anyway ... my question is "what is the bug ?"
Is it that 'eq' overloading has not been provided ? (Providing such overloading successfully works around the problem.)
Is it that Test::More (or Test::Builder) should not be assuming that 'eq' has been overloaded ?
Or has Test::Builder tried (and failed) to account for this possibility. I'm looking at $self->$unoverload( \$got, \$expect ) in the above snippet from Builder.pm, and wondering what that might be intended to do.

With math objects, I've never felt the need to be able to compare $obj eq $str. If I need to do that I just make use of the overloaded stringification and compare "$obj" eq $str.

I'm interested to hear thoughts on what is the "correct" way to deal with this issue.

Cheers,
Rob