Ruby ซ่อน errors/exceptions บางอย่าง ไม่ให้คุณเห็น บางครั้งมีประโยชน์ (เช่น Kernel#loop หยุดเมื่อ StopIteration) แต่บางครั้งทำให้ debug ยาก
Hidden Exception: Comparable Module + <=> Method
class MyObject
attr_accessor :value
include Comparable
def initialize(value); @value = value; end
def <=>(other)
raise ArgumentError, "can't compare" unless other.is_a?(MyObject)
value <=> other.valuee # typo: valuee!
end
end
mo1 = MyObject.new(10); mo2 = MyObject.new(10)
p mo1 == mo2 # false (แทนที่จะ error!)
Typo valuee ควรได้ NoMethodError แต่ Ruby ซ่อนไว้ (Comparable เรียก <=> และกลืน exception) Ruby 2.3+ แก้แล้ว แสดง error ปกติ
Hidden Exception: Numeric Object + Coercion Method
class MyObject
attr_accessor :value
def initialize(value); @value = value; end
def +(other)
other = MyObject.new(other) if other.kind_of?(Numeric)
value + other.value
end
def coerce(other)
mo = MyObject.new
mo.valuee = other # typo!
[mo, self]
end
end
mo1 = MyObject.new(10)
20 + mo1 # "MyObject can't be coerced into Fixnum" (ข้อความผิด! จริงๆคือ typo valuee)
coerce ใช้ทำงานกับ incompatible types Integer#+ จะเรียก coerce ของอ็อบเจ็กต์เรา Ruby 2.5+ แก้แล้ว
Summary
ตัวอย่างดีว่าทำไมไม่ควรซ่อน exceptions อ่านเพิ่มในหนังสือ Ruby Deep Dive