What is the difference between `Range#include?` and `Range#cover?`?

range, ruby

Solution

The two methods are designed to do two slightly different things on purpose. Internally they are implemented very differently too. You can take a look at the sources in the documentation and see that `.include?` is doing a lot more than `.cover?`

The `.cover?` method is related to the `Comparable` module, and checks whether an item would fit between the end points in a sorted list. It will return true even if the item is not in the set implied by the `Range`.

The `.include?` method is related to the `Enumerable` module, and checks whether an item is actually in the complete set implied by the `Range`. There is some finessing with numerics - Integer ranges are counted as including all the implied `Float` values (I'm not sure why).

These examples might help:

('a'..'z').cover?('yellow')
# => true

('a'..'z').include?('yellow')
# => false

('yellaa'..'yellzz').include?('yellow')
 => true

Additionally, if you try

('aaaaaa'..'zzzzzz').include?('yellow')

you should notice it takes a much longer time than

('aaaaaa'..'zzzzzz').cover?('yellow')

Problem

Edit Fixed following toro2k's comment. `Range#include?` and `Range#cover?` seem to be different as seen in the source code 1, 2, and they are different in efficiency. ``` t = Time.now 500000.times do ("a".."z").include?("g") end puts Time.now - t # => 0.504382493 t = Time.now 500000.times do ("a".."z").cover?("g") end puts Time.now - t # => 0.454867868 ``` Looking at the source code, `Range#include?` seems to be more complex than `Range#cover?`. Why can't `Range#include?` be simply an alias of `Range#cover?` What is their difference?

Original source