Project

General

Profile

Bug #1885

Proper comparison of recursive Struct & Range

Added by marcandre (Marc-Andre Lafortune) over 10 years ago. Updated over 8 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 1.9.2dev (2009-08-05 trunk 24397) [i386-darwin9.7.0]
Backport:
[ruby-core:24759]

Description

=begin
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)
=end


Files

struct_comparison.diff (1.94 KB) struct_comparison.diff marcandre (Marc-Andre Lafortune), 08/31/2009 04:17 AM

History

#1

Updated by marcandre (Marc-Andre Lafortune) over 10 years ago

=begin
Here is a patch for the latest 1.9.x that fixes comparison between recursive Struct. The right result is now returned, instead of looping forever. Note: this fixes Struct only; Range has not been patched. Rubyspecs have been updated.
=end

#2

Updated by marcandre (Marc-Andre Lafortune) about 10 years ago

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

=begin
Applied in changeset r25010.
=end

Also available in: Atom PDF