Skip to content

RubyArray.subList should treat toIndex as exclusive, not inclusive. #1274

@masover

Description

@masover

That is, if I pass a ruby array to something expecting a list, and it calls myArray.subList(0,1), it should receive a one-element sublist, not a two-element sublist. Similarly, myArray.subList(0, myArray.size()) should return the entire array, even though size() is one past the last valid index.

The source for subList includes:

IRubyObject subList = subseq(fromIndex, toIndex - fromIndex + 1);

It looks like subseq expects an offset and a length. However, from the Java API docs:

Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive.

So the length of that range should be toIndex - fromIndex. We can see this in the behavior of such a list:

public static void testList(List<?> items) {
  System.out.println("Received " + items.size() + " items");
  System.out.println("sublist(0,1).size() is " + items.subList(0,1).size());
}

Call this with an ArrayList, and it gives a sublist of size 1. Call it from JRuby with a Ruby array, and it gives a sublist of size 2. (A workaround in JRuby is to explicitly construct an ArrayList and addAll() the Ruby array, but that's silly.)

To fix: Just change it to:

IRubyObject subList = subseq(fromIndex, toIndex - fromIndex);

I'll generate a pull request if it really helps, but this should be a one-liner. Even the bounds check is correct (it allows toIndex==size() (should return a sublist ending at the end of the list), and it allows fromIndex==toIndex (should return an empty sublist)).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions