Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
None
Description
When treating Strings as an iterable collection of characters, Groovy provides each character as a String of size 1, e.g.:
assert "hello".toList() == ['h', 'e', 'l', 'l', 'o'] assert "hello".toList()[0].class.name == 'java.lang.String' "hello".each { assert it instanceof String }
There are just 3 methods where this isn't the case:
takeWhile, dropWhile and collectReplacements.
These methods supply a Character instead, e.g.:
assert "he" == "hello".takeWhile { assert it instanceof Character it != 'l' }
This issue is to fix this inconsistency. This is a breaking change but of low impact:
- Most expressions within the closure such as it != 'A' or it < 'B' will produce the same results regardless of whether a String or character is passed in.
- Expressions using methods from the String class would have needed an "as String" or ".toString()" coercion/conversion. These will still work unchanged but the coercion will no longer be required.(Which aligns them with the expressions for all other String iteration methods.)
- Closures with an explicit String arg currently don't work but would work after the change.
- Closures making use of instance methods from the Character class are breaking but those methods are "charValue()" and "compareTo(Character anotherCharacter)" and are likely rarely used (there use would be non-idiomatic Groovy).
In any case, I propose supporting the detection of supplied Closures having a char or Character argument in which case the char would be passed in as now. This would make fixing the break trivial for those cases.
Attachments
Issue Links
- depends upon
-
GROOVY-7434 Groovy should support resolving ambiguous signatures when using ClosureParams
- Closed
- relates to
-
GROOVY-7432 Enhance CharSequence with appropriate Iterable extension methods
- Closed