Issue #16678 has been updated by Dan0042 (Daniel DeLorme).


Negative indices have always meant "offset from the end" in ruby. So if you take a negative index and add the size of the array you get the "normal index" and then I think you'll see everything is pretty intuitive.

```ruby
a = (1..5).to_a

# get all values from a[-4] (a[1]) to a[3]
a.values_at(-4..3) #=> [2, 3, 4]
a.values_at(1..3)  #=> [2, 3, 4]

# get all values from a[-1] (a[4]) to a[3]
a.values_at(-1..3) #=> []
a.values_at(4..3)  #=> []  #range start > range end = empty range, therefore empty array
```

But I think this is slightly inconsistent:

```ruby
(4..6).map{ a[_1] } #=> [5, nil, nil]
a.values_at(4..6)   #=> [5, nil, nil]

(-7..-5).map{ a[_1] } #=> [nil, nil, 1]
a.values_at(-7..-5)   #=> RangeError (-7..-5 out of range), should be [nil, nil, 1] imho
```

----------------------------------------
Misc #16678: Array#values_at has unintuitive behavior when supplied a range starting with negative index
https://bugs.ruby-lang.org/issues/16678#change-84554

* Author: prajjwal (Prajjwal Singh)
* Status: Open
* Priority: Normal
----------------------------------------
Consider the following:

``` ruby
# frozen_string_literal: true

a = (1..5).to_a

p a.values_at(3..5) # => [4, 5, nil]
p a.values_at(-1..3)  # => []
```

When the range begins with a negative `(-1, 0, 1, 2, 3)`, it returns an empty array, which surprised me because I was expecting `[1, 2, 3, 4]`.

The argument for this is that it cold be confusing to allow this because the index `-1` could refer to the last argument and it would be unintuitive to return an array `[5, 1, 2, 3, 4]` with jumbled values.

The argument against it is that it makes perfect sense to account for this case and return `[nil, 1, 2, 3, 4]`.

Opening a dialog to see what others think of this.




-- 
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>