From: "zakhar (Isaac Schwabacher)" Date: 2013-10-30T03:50:15+09:00 Subject: [ruby-core:58070] [ruby-trunk - Bug #9059][Open] Equal Time objects don't hash equal Issue #9059 has been reported by zakhar (Isaac Schwabacher). ---------------------------------------- Bug #9059: Equal Time objects don't hash equal https://bugs.ruby-lang.org/issues/9059 Author: zakhar (Isaac Schwabacher) Status: Open Priority: Normal Assignee: Category: Target version: ruby -v: ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0] Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN =begin Time objects break the promise that if (({t0.eql? t1})), then (({t0.hash == t1.hash})). It is possible that this is related to the resolution of (()), since both issues seem to be related to round-off error. #!/usr/bin/env ruby require 'minitest/autorun' describe Object do before do t0 = Time.new(2013, 10, 29, 12, 30, 27) t1 = t0 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 t_midnight = Time.new(2013, 10, 29) @x = t0 - (t0.to_r - t_midnight.to_r) % 60 @y = t1 - (t1.to_r - t_midnight.to_r) % 60 end it "should hash equal to eql objects" do if @x.respond_to? :eql? and @x.respond_to? :hash and @y.respond_to? :hash @x.hash.must_equal @y.hash if @x.eql? @y end end end This test also failed on ruby -v ((%ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]%)). If I had to guess, I would say that the instance variables from which (({@t0.tv_*})) and (({@t1.tv_*})) are computed are (({#==})) but not (({#eql?})), and that (({Time#eql?})) is (correctly, I think) using (({#==})) to compare these, but (({Time#hash})) is using their (({#hash}))es directly rather than converting them to a common type first. =end -- http://bugs.ruby-lang.org/