As a follow-up to this question
Here is some code that compiles and runs correctly, using captures.
val myString = "ACATCGTAGCTGCTAGCTG"
val nucCap = "([ACTG]+)".r
myString match {
case nucCap(myNuc) => println("dna:"+myNuc)
case _ => println("not dna")
}
>scala scalaTest.scala
dna:ACATCGTAGCTGCTAGCTG
Here is simpler code, without capture, that does not compile.
val myString = "ACATCGTAGCTGCTAGCTG"
val nuc = "[ACGT]+".r
myString match {
case nuc => println("dna")
case _ => println("not dna")
}
>scala scalaTest.scala
scalaTest.scala:7: error: unreachable code
Seems like the matching should return a boolean regardless of whether a capture is used.
What is going on here?
In your
matchblock,nucis a pattern variable and does not refer to thenucin the enclosing scope. This makes the default case unreachable because the simple patternnucwill match anything.An empty pair of parentheses on
nucwill make the syntactic sugar work and call theunapplySeqmethod on the Regex:One way to avoid this pitfall is to rename
nuctoNuc. Starting with an uppercase letter makes it a stable identifier, so that it refers to theNucin the enclosing scope, rather than being treated by the compiler as a pattern variable.The above will print
"not dna", because here we are simply comparingNuctomyString, and they are not equal. It’s a bug, but maybe a less confusing one!Adding the parentheses will have the desired effect in this case too:
By the way, it is not a boolean that is being returned, but an
Option[List[String]]: