Issue #16812 has been updated by zverok (Victor Shepelev).


As there is no immediate rejection, I updated the implementation, making it more robust.

@Dan0042, I tried to make edge cases consistent, so now they are...

```ruby
(0..20).to_a[10.step(by: -2)]
# => [10, 8, 6, 4, 2, 0] -- avoids weird cycling
(0..20).to_a[(-5..5) % 2]
# => [] -- this is consistent with
(0..20).to_a[-5..5] # which can be thought as (-5..5) % 1
# => [] 
# Note, though:
(0..20).to_a[-19..5]
# => [2, 3, 4, 5] -- not literally "from -19 to 5", but "from 19th from the end to 5th from the beginning"
# ...so...
(0..20).to_a[(-19..5)%2]
# => [2, 4]
```

@nobu I've tried to fix bugs. Now float begin/end is processed correctly, float step is TypeError, and the code does not rely on `#take_while`/`#drop_while`.

@mrkn I've checked against Python impl, and believe the behavior is mostly the same. One difference I am aware of is this:

Python:
```python
list(range(10))[-100:100:2]                                                                                                            
#=> [0, 2, 4, 6, 8]
```
Ruby:
```ruby
[*0..10][(-100..100)%2]
# => nil
```
That's because first of all I wanted to make it consistent with
```ruby
[*0..10][-100..100]
# => nil
```
...which may be questioned (like, "range from -100 to 100 includes 0..10, so it should fetch entire array"), but that's how it is now :)

----------------------------------------
Feature #16812: Allow slicing arrays with ArithmeticSequence
https://bugs.ruby-lang.org/issues/16812#change-85291

* Author: zverok (Victor Shepelev)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
I believe when concepts of ArithmeticSequence and `Range#%` were introduced, one of the main intended usages was array slicing in scientific data processing. So, it seems to make sense to allow this in `Array#[]`:

```ruby
ary[(5..20) % 2] # each second element between 5 and 20
ary[(0..) % 3] # each third element
ary[10.step(by: -1)] # elements 10, 9, 8, 7 ....
```

PR is [here](https://github.com/ruby/ruby/pull/3055).

My reasoning is as follows:
1. As stated above, ArithmeticSequence and `Range#%` seem to have been introduced exactly for this goal
2. Python has its slicing syntax as `begin:end:step` (with a possibility to omit either), and it seems to be well respected and used feature for data processing. So I believe it is useful, and relatively easy to integrate into existing functionality

I expect the usual "it is ugly and unreadable!" backlash. 
I don't have an incentive, nor energy, to "defend" the proposal, so I would not.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>