From: owen@... Date: 2018-05-19T09:22:12+00:00 Subject: [ruby-core:87190] [Ruby trunk Feature#14777] Add Range#offset ? Issue #14777 has been reported by owst (Owen Stephens). ---------------------------------------- Feature #14777: Add Range#offset ? https://bugs.ruby-lang.org/issues/14777 * Author: owst (Owen Stephens) * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- Hi, As mentioned in https://bugs.ruby-lang.org/issues/14473#note-17 an addition to Range that we find useful is an `Range#offset(n)` method that adds (or subtracts) `n` to the range, for example: ~~~ruby (1..10).offset(2) # => (3..12) (1...10).offset(1) # => (2...11) (1..10).offset(-10) # => (-9..0) ~~~ Similarly to `Range#step` we can support non-Numeric objects if they implement `succ`: ~~~ruby ('a'..'e').offset(2) # => ('c'..'g') ~~~ Alternative names could be `Range#shift` (i.e. shift the elements of the Range up or down) or perhaps `>>`/`<<`: ~~~ruby (1..10).shift(2) # => (3..12) (1..10) >> 2 # => (3..12) (1...10) << 1 # => (0...9) ~~~ However, I don't think the operators are clear enough, so I prefer `offset` or `shift`. An example pure Ruby implementation is: ~~~ruby class Range def offset(n) add_n = ->(x) do if x.is_a?(Numeric) x + n elsif x.respond_to?(:succ) n.times { x = x.succ } x else raise ArgumentError, "Can't offset #{x.class}" end end if exclude_end? (add_n.call(first)...add_n.call(last)) else (add_n.call(first)..add_n.call(last)) end end end ~~~ Please let me know your thoughts, I can then look to implement this properly in C. Regards, Owen. -- https://bugs.ruby-lang.org/ Unsubscribe: