Feature #5534

Redefine Range class and introduce RelativeNumeric and RelativeRange

Added by alexeymuranov (Alexey Muranov) over 8 years ago. Updated over 7 years ago.

Target version:


I started by commenting on Feature #4541, but ended up with proposing a new feature myself.

I suggest to redefine the behavior of Range class so that all empty ranges be equal:

(2..1) == (1..-1) and (2..1) == (1...1) and (2..1) == ('z'..'a') # => true

In other fords, ranges r1 and r2 should be equal if and only if r1.include? and r2.include? give identical results for all inputs. (Why is it not includes? by the way?) Thus Range would simply be a way to store certain infinite sets.

This change will result in not being able to slice an array a from beginning and from the end simultaneously with a[1..-2]. To resolve this, i propose to introduce RelativeNumeric and RelativeRange classes.

Each RelativeNumeric would be a Numeric with an "anchor", which is an arbitrary symbol. For example:

3.from(:bottom) # would return a "relative" 3 with "anchor" :bottom

One can define shortcuts #from_bottom for #from(:bottom) and #from_top for #from_top.

A RelativeRange is a range with relative bounds. If bounds of a relative range r are relative to the same anchor and the range is seen to be empty, it should be equal to the empty relative range with this anchor. For example:

(3.from(:center)..2.from(:center)) == (0.from(:center)...0.from(:center)) # => true

Now, to do what is currently done by a[1..-2], one can redefine Array#slice to use instead:


What do you think?

Also available in: Atom PDF