From: andrew@... Date: 2015-05-01T23:02:33+00:00 Subject: [ruby-core:69056] [Ruby trunk - Bug #11113] Time ranges cannot be used in case statements in 1.9+ but they could in 1.8.7 Issue #11113 has been updated by Andrew Vit. Good point, it looks like Float is already "covered" (I didn't check) so it's only Time that is the issue here. > Seems like something like range.begin < other && range.end > other would perform better (constant time) Yes, that's exactly what `cover?` does, instead of iterating with `include?`. ---------------------------------------- Bug #11113: Time ranges cannot be used in case statements in 1.9+ but they could in 1.8.7 https://bugs.ruby-lang.org/issues/11113#change-52309 * Author: Myron Marston * Status: Open * Priority: Normal * Assignee: * ruby -v: 1.9.2, 1.9.3, 2.0, 2.1, 2.2 * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN ---------------------------------------- Given this script: ```ruby range = (Time.now - 1000)...(Time.now + 1000) case Time.now when range then puts "in range" else puts "not in range" end ``` I'd expect it to print "in range". This worked on 1.8.7: ``` $ ruby -v time_range_problem.rb ruby 1.8.7 (2013-12-22 patchlevel 375) [i686-darwin12.5.0] in range ``` ...but raises an exception in 1.9.2, 1.9.3, 2.0, 2.1 and 2.2: ``` time_range_problem.rb:4:in `each': can't iterate from Time (TypeError) from time_range_problem.rb:4:in `include?' from time_range_problem.rb:4:in `include?' from time_range_problem.rb:4:in `===' from time_range_problem.rb:4:in `
' ``` It looks like `Range#===` is broken. Given that `===` is a standard ruby protocol, I would not expect a built-in type to raise an error like this. IMO, `===` should either return true or false but should not raise an error. We rely upon `===` in RSpec to do matching and this behavior means that if users pass us a time range, things blow up. See https://github.com/rspec/rspec-mocks/issues/938 for an example. -- https://bugs.ruby-lang.org/