diff --git a/ChangeLog b/ChangeLog index 381b582aaf..059a55f23f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Sun Jan 19 06:38:48 2014 Benoit Daloze + + * compar.c (cmp_equal): warn for this release and still rescue + standard exceptions for a nicer transition. See #7688. + Partly reverts r44502. + + * test/ruby/test_comparable.rb: adapt assertion to match new behavior. + +Sun Jan 19 06:27:18 2014 Benoit Daloze + + * test/ruby/test_comparable.rb: specify behavior for the different + kind of exceptions rescued (or not) by Comparable#==. + Sat Jan 18 23:12:19 2014 Tanaka Akira * ext/socket: Avoid unnecessary ppoll/select on Linux. diff --git a/compar.c b/compar.c index 8ce5c54287..893cde79fc 100644 --- a/compar.c +++ b/compar.c @@ -58,6 +58,24 @@ cmp_eq_recursive(VALUE arg1, VALUE arg2, int recursive) return rb_funcallv(arg1, cmp, 1, &arg2); } +static VALUE +cmp_eq(VALUE *a) +{ + VALUE c = rb_exec_recursive_paired_outer(cmp_eq_recursive, a[0], a[1], a[1]); + + if (NIL_P(c)) return Qfalse; + if (rb_cmpint(c, a[0], a[1]) == 0) return Qtrue; + return Qfalse; +} + +static VALUE +cmp_failed(void) +{ + rb_warn("Comparable#== will no more rescue exceptions of #<=> in the next release."); + rb_warn("Return nil in #<=> if the comparison is inappropriate or avoid such comparison."); + return Qfalse; +} + /* * call-seq: * obj == other -> true or false @@ -73,14 +91,12 @@ cmp_eq_recursive(VALUE arg1, VALUE arg2, int recursive) static VALUE cmp_equal(VALUE x, VALUE y) { - VALUE c; + VALUE a[2]; + if (x == y) return Qtrue; - c = rb_exec_recursive_paired_outer(cmp_eq_recursive, x, y, y); - - if (NIL_P(c)) return Qfalse; - if (rb_cmpint(c, x, y) == 0) return Qtrue; - return Qfalse; + a[0] = x; a[1] = y; + return rb_rescue(cmp_eq, (VALUE)a, cmp_failed, 0); } /* diff --git a/test/ruby/test_comparable.rb b/test/ruby/test_comparable.rb index e734e8b979..05426af139 100644 --- a/test/ruby/test_comparable.rb +++ b/test/ruby/test_comparable.rb @@ -1,4 +1,5 @@ require 'test/unit' +require_relative 'envutil' class TestComparable < Test::Unit::TestCase def setup @@ -20,8 +21,9 @@ class TestComparable < Test::Unit::TestCase cmp->(x) do raise NotImplementedError, "Not a RuntimeError" end assert_raise(NotImplementedError) { @o == nil } bug7688 = '[ruby-core:51389] [Bug #7688]' - cmp->(x) do raise StandardError, "Even a standard error should not be rescued"; end - assert_raise(StandardError, bug7688) { @o == nil } + cmp->(x) do raise StandardError, "A standard error should be rescued"; end + warn = /Comparable#== will no more rescue exceptions .+ in the next release/ + assert_warn(warn, bug7688) { @o == nil } end def test_gt