I’m porting old code to new versions of Scala and have a varargs match that no longer compiles. The closest I come to the old version is this new version, but it does not have the exact same behavior when there is no text, and in fact the compiler seems to warn me about it with
A repeated case parameter or extracted sequence is not matched by a sequence wildcard (_*), and may fail at runtime.
The old version will match all of
<sub>{"text"}</sub>
<sub>{" "}</sub>
<sub></sub>
but the new version does not match the last one. Is there a new syntax that will do this, one that may still compile under old Scala versions? I can add an extra case <sub></sub> => to catch it, but would rather not.
def transform(n: Node): String = n match {
// case <sub>{text @ _*}</sub> => // old version
case <sub>{Seq(text @ _*)}</sub> => // new version
text.text
case _ => "non-match"
}
In addition to the range of Scala versions you are trying to target, it’s especially important to tell us precisely what version of scala-xml is on your classpath, as the semantics of pattern matches could conceivably be affected by changes such as the one at the top of the scala-xml 2.4.0 release notes: Release 2.4.0 · scala/scala-xml · GitHub
That is a Scala 2 warning, so more info about versions and how you’re building would be needed to help, as already mentioned. Hopefully it’s just a stale dependency.
//> using jvm 8
//> using scala 2.12.21
//> using dep org.scala-lang.modules::scala-xml:1.3.1
import scala.xml.Node
def transform(n: Node): Unit = {
val transformed = n match {
case <sub>{text @ _*}</sub> => text.text // old version
case _ => "non-match"
}
println(s"""The result is "$transformed".""")
}
transform(<sub>{"text"}</sub>)
transform(<sub>{" "}</sub>)
transform(<sub>{""}</sub>)
transform(<sub></sub>)
transform(<sub/>)
and here’s the Scala 3.3 version for which transform also works for Scala 2, both needing the commented out extra line to match original output
//> using jvm 8
//> using scala 3.3.7
//> using dep org.scala-lang.modules::scala-xml:2.4.0
import scala.xml.Node
def transform(n: Node): Unit = {
val transformed = n match {
// case <sub>{text @ _*}</sub> => text.text // does not compile
case <sub>{Seq(text @ _*)}</sub> => text.text // new version
// case <sub/> => "" // extra line required
case _ => "non-match"
}
println(s"""The result is "$transformed".""")
}
transform(<sub>{"text"}</sub>)
transform(<sub>{" "}</sub>)
transform(<sub>{""}</sub>)
transform(<sub></sub>)
transform(<sub/>)
So I wonder if there is any way to get the new version to work without including the extra line with the additional case.