Search code examples
rubyexceptionrescue

What is wrong with this rescue example?


x = StandardError.new(:hello)
y = StandardError.new(:hello)
x == y # => true
x === y # => true

begin
  raise x
rescue x
  puts "ok" # gets printed
end

begin
  raise x
rescue y
  puts "ok" # doesn't get printed
end

Why isn't the second "ok" printed? I can't figure it out. I've read here that ruby uses the === operator to match exceptions to rescue clauses, but that's ostensibly not the case.

I'm using Ruby 1.9.3

EDIT: So it seems like that after doing raise x, x == y and x === y no longer hold. It seems to because x and y no longer have the same backtrace.


Solution

  • I just want to add something to the table: OP code suggests that the two exceptions are the same but they are not - furthermore i want to illustrate what OP meant with:

    So it seems like that after doing raise x, x == y and x === y no longer hold. It seems to because x and y no longer have the same backtrace.

     x = StandardError.new(:hello)
     y = StandardError.new(:hello)
     class Object
       def all_equals(o)
         ops = [:==, :===, :eql?, :equal?]
         Hash[ops.map(&:to_s).zip(ops.map {|s| send(s, o) })]
       end
     end
    
     puts x.all_equals y # => {"=="=>true, "==="=>true, "eql?"=>false, "equal?"=>false}
    
     begin
       raise x
     rescue
       puts "ok" # gets printed
     end
    
     puts x.all_equals y # => {"=="=>false, "==="=>false, "eql?"=>false, "equal?"=>false}