Bug #18577
closedRange#include? returns wrong result for beginless range with exclusive string end
Description
Exclusive range should not include the end value, but (...'z').include? 'z'
returns true. member?
and ===
behave in the same way, while cover?
does not.
This happens when the range is beginless and its end is string.
irb(main):001:0> (...'z').include? 'z'
=> true
irb(main):002:0> (...'z').member? 'z'
=> true
irb(main):003:0> (...'z') === 'z'
=> true
irb(main):004:0> (...'z').cover? 'z'
=> false
Updated by zverok (Victor Shepelev) almost 3 years ago
It seems that the cause is unnecessary (?) specialization of Range#include?
for String arguments.
I believe string ranges should just fallback to the default implementation:
(...Date.today) === Date.today
# => false
(...Date.today).cover? Date.today
# => false
(...Date.today).include? Date.today
# in `each': can't iterate from NilClass (TypeError)
The removal of specialization will also fix current (and possible future) discrepancies of Range#cover?
and Range#===
for String ranges.
If it is not acceptable (some cases of backward compatibility?), this statement should be fixed.
Updated by jeremyevans0 (Jeremy Evans) almost 3 years ago
zverok (Victor Shepelev) wrote in #note-1:
It seems that the cause is unnecessary (?) specialization of
Range#include?
for String arguments.I believe string ranges should just fallback to the default implementation:
(...Date.today) === Date.today # => false (...Date.today).cover? Date.today # => false (...Date.today).include? Date.today # in `each': can't iterate from NilClass (TypeError)
The removal of specialization will also fix current (and possible future) discrepancies of
Range#cover?
andRange#===
for String ranges.
If you want to remove the specialization, that's something that probably should be discussed at a developer meeting. I am against removing it. Not because I think the specialization is a good idea, but because I don't think it's worth breaking backwards compatibility (raising TypeError for previously working code).
If it is not acceptable (some cases of backward compatibility?), this statement should be fixed.
I submitted a pull request to fix this: https://github.com/ruby/ruby/pull/5541
Updated by jeremyevans (Jeremy Evans) almost 3 years ago
- Status changed from Open to Closed
Applied in changeset git|fd710d7e9995679db80b7adf35bbda2cd4db90c6.
Fix Range#include? for beginless exclusive string ranges
Previously, include? would return true for the end of the range,
when it should return false because the range is exclusive.
Research and Analysis by Victor Shepelev.
Fixes [Bug #18577]