String.substring(-3)

You are here:

The String.substring(int) method should permit negative indeces. myString.substring(-3) should return the same as myString.substring(myString.length()-3) i.e. the last three characters.

It's only somewhat annoying with named Strings to have to write the name twice, but with unnamed calculated Strings it's really bothersome sometimes. One has to assign the String to a temporary variable just to be able to get the last n characters.

> Suffer as much as the person who copied the Perl hack
> for String.split?

Perl hack? What do you not like about String.split?

> Bugs may go unnoticed if something is returned
> instead of throwing an exception

That is true. But other languages like Python allow it, too, and it's not really a problem. You only get the IndexOutOfBoundsException at runtime, and in the same case you would also see the messed-up result of the strings with only the last characters instead of the first ones like intended.

But String.tail(int) and String.tail(int,int) would be fine to prevent that problem.

> Really odd that it should be a length when substring
> otherwise takes indexes as arguments.
> String.substring gives a substring from the supplied
> index, not the a String of given length.

I never suggested that. myString.substring(-3) is simply myString.substring(myString.length()-3), so -3 is the index counted from the right side, not the length.

The negative index is going to break the current contract, the tail() or rightString() idea is great, as it would still throw an IndexOutOfBoundsException for myString.tail(4) (I would assume it becomes myString.substring(myString.length() - 4, myString.length()) and this would throw the appropiate IndexOutOfBoundsException.

> If myString.length() is 2, then what are you going to
> get with myString.length(-4)
>
> This would map to myString.length(2 - 4) =>
> myString.length(-2) => myString.length(2 - 2) =>
> myString.length(0);

It would only do this if it were defined and implemented recursively, and not test for permitted indeces first (which it does, otherwise it would throw an ArrayIndexOutOfBoundsException, not an IndexOutOfBoundsException).

> Other languages like Python allow it, too.
>
ah, another argument "because XXXXX has it, so should Java"...

If we go that way and implement everything in Java that's in any other language we're probably in for a very rude awakening as many things may well work completely contradictory in different languages...

Suffer as much as the person who copied the Perl hack for String.split?

Bugs may go unnoticed if something is returned instead of throwing an exception, when indexes are miscalculated. It's not in anyway obvious what it does, particular if the length is calculated. Really odd that it should be a length when substring otherwise takes indexes as arguments. String.substring gives a substring from the supplied index, not the a String of given length. The idea that anything that could possible have an interpretation should have an arbitrary one is not helpful, IMO.