Burdette Lamar

Posted on

# This is Weird

For Array `a`, I'm doing `a[range] = obj`. Here's what I think I see:

If `range.end` is negative, assigns `obj` at offset `start`, retains `range.end.abs-1` elements past that, and removes those beyond:

``````a = [:foo, 'bar', baz = 2]
a[1..-1] = 'foo' # => "foo"
a # => [:foo, "foo"]
a = [:foo, 'bar', baz = 2]
a[1..-2] = 'foo' # => "foo"
a # => [:foo, "foo", 2]
a = [:foo, 'bar', baz = 2]
a[1..-3] = 'foo' # => "foo"
a # => [:foo, "foo", "bar", 2]
a = [:foo, 'bar', baz = 2]
a[1..-4] = 'foo' # => "foo"
a # => [:foo, "foo", "bar", 2]
``````

Ken Bellows

I think what's happening is:

• The elements covered by the range are replaced by the assigned value
• Negative indexes are used as offsets from the end of the array. So `a[-2]` is the same as `a[a.length - 2]`, and `a[1..-2]` is the same as `a[1..a.length-2]`
• When the end index of a range is `<=` the start index, no values are replaced
``````a = [:foo, 'bar', baz = 2]
a[1..-1]  # 1..-1 is the same as 1..2 because a.length is 3
# => ["bar", 2]
a[1..-1] = 'foo'  # this is the same as removing "bar" and 2 from a and replacing them with "foo"
# => [:foo, "test"]
``````

Burdette Lamar

Yes. Good interpretation. (But still weird, I think.)