10

Problem description Scala StringOps provides a lines method that returns an Iterator[String]. Java 11 added lines() with return type java.Stream[String].

In a chained method call like

val text: String
text.lines.foldLeft("")(_ + _)

the code will no longer compile and throw an exeption that foldLeft is not defined on java.Stream[String]. As far as I understand the implicit resolution is no longer applied as the lines method now is already found in java.String.

How can I express that I want the implicit to be applied (the one without parens) isntead of the java.String.lines()

Additional info

  • I found linesIterator but it is deprecated.
  • Downgrading is an option but is there a way around it.
  • val text : StringOps looks realy ugly but solved it but I am unhappy with this solution
Andreas Neumann
  • 10,734
  • 1
  • 32
  • 52

2 Answers2

18

The conflict between StringOps#lines and jdk11 java.lang.String#lines is a bug in scala, see issue 11125.

The fix for this bug is to un-deprecate linesIterator, which was done in 2.12.7.

Welcome to Scala 2.12.7 (OpenJDK 64-Bit Server VM, Java 11).

scala> "a".lines
res0: java.util.stream.Stream[String] = java.util.stream.ReferencePipeline$Head@2df259d0

scala> "a".linesIterator
res1: Iterator[String] = <iterator>
obourgain
  • 8,856
  • 6
  • 42
  • 57
5

You can force Scala to use the implicit conversion to StringOps, which will use the old lines method:

(text: StringOps).lines.foldLeft("")(_ + _)
Clashsoft
  • 11,553
  • 5
  • 40
  • 79
  • This and inserting `augmentString` are equivalent, can't think of a strong reason to prefer one or the other. ( But note that `StringOps` is in `scala.collection.immutable` and isn't imported by default.) – Seth Tisue Oct 16 '18 at 22:00