From: Marc-Andre Lafortune Date: 2009-08-05T05:30:39+09:00 Subject: [ruby-core:24759] [Bug #1885] Proper comparison of recursive Struct & Range Bug #1885: Proper comparison of recursive Struct & Range http://redmine.ruby-lang.org/issues/show/1885 Author: Marc-Andre Lafortune Status: Open, Priority: Normal Category: core ruby -v: ruby 1.9.2dev (2009-08-05 trunk 24397) [i386-darwin9.7.0] The following code freezes the latest ruby 1.9: MyClass = Struct.new(:foo) x = MyClass.new; x[:foo] = x y = MyClass.new; y[:foo] = y x == y # Loops forever (can not be interrupted) Solution: rb_struct_equal & rb_struct_eql should handle recursion in a similar fashion as Array and Hash (i.e. by calling rb_exec_recursive_paired and returning Qtrue if recursion is detected). I could make a patch if needed. Searching the source code for rb_exec_recursive revealed that Range is potentially recursive too (see range_inspect). The ==, eql? and === methods do not call rb_exec_recursive_paired and are thus also potentially troublesome. To build a recursive Range is not trivial though; either some intermediate container class is needed or else some crazy thing like: class CrazyRange < Range def initialize super(self..self) end def <=>(x) 0 # Needed so CrazyRange can be the begin and end values of a range... end end CrazyRange.new == CrazyRange.new # Loops forever (can not be interrupted) I'm not sure that it is worth modifying ==, eql? and === to use rb_exec_recursive_paired and make them bulletproof. Note that both Struct#hash and Range#hash face the same issue than Array#hash & Hash#hash (see issue #1852) ---------------------------------------- http://redmine.ruby-lang.org