diff --git a/string.c b/string.c index c63f59a..ed02111 100644 --- a/string.c +++ b/string.c @@ -2382,29 +2382,27 @@ rb_str_eql(VALUE str1, VALUE str2) static VALUE rb_str_cmp_m(VALUE str1, VALUE str2) { - long result; + int result; + VALUE tmp; - if (!RB_TYPE_P(str2, T_STRING)) { - if (!rb_respond_to(str2, rb_intern("to_str"))) { - return Qnil; - } - else if (!rb_respond_to(str2, rb_intern("<=>"))) { - return Qnil; - } + if (RB_TYPE_P(str2, T_STRING)) { + result = rb_str_cmp(str1, str2); + } + else { + tmp = rb_check_funcall(str2, rb_intern("to_str"), 0, 0); + if (tmp != Qundef && RB_TYPE_P(tmp, T_STRING)) { + result = rb_str_cmp(str1, tmp); + } else { - VALUE tmp = rb_funcall(str2, rb_intern("<=>"), 1, str1); - + tmp = rb_funcall(str2, rb_intern("<=>"), 1, str1); if (NIL_P(tmp)) return Qnil; - if (!FIXNUM_P(tmp)) { - return rb_funcall(LONG2FIX(0), '-', 1, tmp); - } - result = -FIX2LONG(tmp); + + result = -rb_cmpint(tmp, str1, str2); } } - else { - result = rb_str_cmp(str1, str2); - } - return LONG2NUM(result); + if (result == 0) return INT2FIX(0); + if (result > 0) return INT2FIX(1); + return INT2FIX(-1); } /* diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index 9f63847..cbad9a1 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -170,8 +170,9 @@ class TestString < Test::Unit::TestCase o = Object.new def o.to_str; "bar"; end - assert_nil("foo" <=> o) + assert_equal(1, "foo" <=> o) + class << o;remove_method :to_str;end def o.<=>(x); nil; end assert_nil("foo" <=> o) @@ -181,7 +182,7 @@ class TestString < Test::Unit::TestCase class << o;remove_method :<=>;end def o.<=>(x); 2**100; end - assert_equal(-(2**100), "foo" <=> o) + assert_equal(-1, "foo" <=> o) end def test_EQUAL # '=='