Project

General

Profile

Actions

Bug #5865

closed

Exception#== should return false if the classes differ

Added by hasari (Hiro Asari) over 12 years ago. Updated over 12 years ago.

Status:
Closed
Target version:
-
ruby -v:
ruby 2.0.0dev (2011-12-31 trunk 34165) [x86_64-darwin11.2.0]
Backport:
[ruby-core:41979]

Description

Documentation says "If obj is not an Exception, returns false. Otherwise, returns true if exc and obj share same class, messages, and backtrace."

However,

$ ruby2.0 -v -e 'x=RuntimeError.new("msg"); y=ScriptError.new("msg"); p x==y'
ruby 2.0.0dev (2011-12-31 trunk 34165) [x86_64-darwin11.2.0]
true


Files

exc_equal.patch (1.09 KB) exc_equal.patch now (Nikolai Weibull), 01/09/2012 10:23 PM

Updated by nobu (Nobuyoshi Nakada) over 12 years ago

=begin
It seems intentional.


r20866 | matz | 2008-12-19 08:42:00 +0900 (Fri, 19 Dec 2008) | 2 lines

  • error.c (exc_equal): duck typing equal to make it transitive.
    [ruby-dev:34880]

But the ML ref is apparently wrong.
=end

Updated by now (Nikolai Weibull) over 12 years ago

I also wrote about this in [ruby-core:41393]. An excerpt:

The commit message says that “duck typing equal to make it
transitive”, but I don’t understand what’s meant by “transitive” in
this case. I don’t think RuntimeError.new('a') should be #== to
StandardError.new('a') or vice versa.

Intentional or not at the time, this is neither expected nor desired behavior.

Updated by hasari (Hiro Asari) over 12 years ago

Can this be assigned to matz for clarification?

Thanks.

Updated by matz (Yukihiro Matsumoto) over 12 years ago

Hi,

In message "Re: [ruby-core:41997] [ruby-trunk - Bug #5865] Exception#== should return false if the classes differ"
on Mon, 9 Jan 2012 15:10:16 +0900, Hiro Asari writes:
|
|Issue #5865 has been updated by Hiro Asari.
|
|
|Can this be assigned to matz for clarification?

See [ruby-dev:34808].

						matz.

Updated by now (Nikolai Weibull) over 12 years ago

On Mon, Jan 9, 2012 at 12:43, Yukihiro Matsumoto wrote:

In message "Re: [ruby-core:41997] [ruby-trunk - Bug #5865] Exception#== should return false if the classes differ"
   on Mon, 9 Jan 2012 15:10:16 +0900, Hiro Asari writes:
|
|Issue #5865 has been updated by Hiro Asari.
|
|Can this be assigned to matz for clarification?

See [ruby-dev:34808].

What’s the use case? (How often do you wrap an Exception in a SimpleDelegator?)

The fix should be to also check the #class of obj against the #class
of exc, not to simply ignore it if the rb_obj_class()es don’t match.
I’ve attached a patch.

SimpleDelegator would then need to delegate class as well, but I can’t
say whether that makes sense or not.

Updated by nobu (Nobuyoshi Nakada) over 12 years ago

Hi,

(12/01/09 22:02), Nikolai Weibull wrote:

The fix should be to also check the #class of obj against the #class
of exc, not to simply ignore it if the rb_obj_class()es don’t match.
I’ve attached a patch.

Fixnum#== works fine with Delegator because of implicit conversion, so
I think Exception should also use same way.


diff --git a/error.c b/error.c
index 6844f99..7185d52 100644
--- a/error.c
+++ b/error.c
@@ -732,10 +732,14 @@ exc_equal(VALUE exc, VALUE obj)
CONST_ID(id_mesg, "mesg");

  if (rb_obj_class(exc) != rb_obj_class(obj)) {
  • ID id_message, id_backtrace;
  • ID id_message, id_backtrace, id_exception;
    CONST_ID(id_message, "message");
    CONST_ID(id_backtrace, "backtrace");

  • CONST_ID(id_exception, "exception");

  • obj = rb_check_funcall(obj, id_exception, 0, 0);

  • if (obj == Qundef) return Qfalse;

  • if (rb_obj_class(exc) != rb_obj_class(obj)) return Qfalse;
    mesg = rb_check_funcall(obj, id_message, 0, 0);
    if (mesg == Qundef) return Qfalse;
    backtrace = rb_check_funcall(obj, id_backtrace, 0, 0);
    diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb
    index 028391d..7226fe2 100644
    --- a/test/ruby/test_exception.rb
    +++ b/test/ruby/test_exception.rb
    @@ -380,4 +380,9 @@ end.join
    load(t.path)
    end
    end

  • def test_equal

  • assert_equal(RuntimeError.new("a"), RuntimeError.new("a"))

  • assert_not_equal(RuntimeError.new("a"), StandardError.new("a"))

  • end
    end

--
Nobu Nakada

Updated by matz (Yukihiro Matsumoto) over 12 years ago

Hi,

OK, I like this patch. Please check in.

						matz.

In message "Re: [ruby-core:42017] Re: [ruby-trunk - Bug #5865] Exception#== should return false if the classes differ"
on Tue, 10 Jan 2012 11:34:25 +0900, Nobuyoshi Nakada writes:
|
|Hi,
|
|(12/01/09 22:02), Nikolai Weibull wrote:
|> The fix should be to also check the #class of obj against the #class
|> of exc, not to simply ignore it if the rb_obj_class()es don$B!G(Bt match.
|> I$B!G(Bve attached a patch.
|
|Fixnum#== works fine with Delegator because of implicit conversion, so
|I think Exception should also use same way.

Updated by now (Nikolai Weibull) over 12 years ago

On Tue, Jan 10, 2012 at 03:34, Nobuyoshi Nakada wrote:

  •       obj = rb_check_funcall(obj, id_exception, 0, 0);
  •       if (obj == Qundef) return Qfalse;
  •       if (rb_obj_class(exc) != rb_obj_class(obj)) return Qfalse;

Ah, much better.

Actions #9

Updated by nobu (Nobuyoshi Nakada) over 12 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r34291.
Hiro, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


Updated by naruse (Yui NARUSE) over 12 years ago

  • Status changed from Closed to Assigned
  • Assignee set to nobu (Nobuyoshi Nakada)
Actions #11

Updated by nobu (Nobuyoshi Nakada) over 12 years ago

  • Status changed from Assigned to Closed

This issue was solved with changeset r34299.
Hiro, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0