From: "alexeymuranov (Alexey Muranov)" Date: 2012-11-28T23:30:13+09:00 Subject: [ruby-core:50259] [ruby-trunk - Feature #5534] Redefine Range class and introduce RelativeNumeric and RelativeRange Issue #5534 has been updated by alexeymuranov (Alexey Muranov). =begin I propose to cancel the second part of my proposal: about (({RelativeNumeric})) and (({RelativeRange})). When i look back at it now, it looks quite crazy and not particularly useful. However, i still would like to see the behavior of (({Range})) changed, as in the first part of the proposal. In other words, i would like (({Range})) become a ((*lazy ordered set*)), infinite or finite. I think i proposed (({RelativeNumeric})) simply because i didn't dare to propose to deprecate the usage like b = a[1..-2] for an array (({a})) without proposing some similarly looking replacement. Now i've decided i would prefer this usage be deprecated. How about a new method (({Array#trim(fixnum, fixnum)})) to write b = a.trim(1,1) instead of b = a[1..-2] ? (I can start a new Feature Request if a discussion is necessary.) It looks strange to have to convert a pair of numbers ((*m*)) and ((*n*)) into a range (({m..(-1-n}))) to simply ask an array to remove ((*m*)) elements from the beginning and ((*n*)) elements from the end. If you think about what the range (({m..(-1-n)})) actually ((*is*)), then the syntax (({a[m..(-1-n)]})) looks plain weird :). =end ---------------------------------------- Feature #5534: Redefine Range class and introduce RelativeNumeric and RelativeRange https://bugs.ruby-lang.org/issues/5534#change-34085 Author: alexeymuranov (Alexey Muranov) Status: Assigned Priority: Normal Assignee: matz (Yukihiro Matsumoto) Category: core Target version: next minor 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: a[1.from_bottom..(-1).from_top] What do you think? -- http://bugs.ruby-lang.org/