I have hit what appears to be an issue with the Scala WorkSheet around using a case class with a private constructor. Below is the entire contents of the Scala WorkSheet named org.public_domain.WorkSheetCaseClassCompanionObject self-containing the problem domain. Below the case class, there is a section marked "incorrect: appears to compile as though the case class apply method..." which contains the 12 lines which appear to be calling the case class private constructor as opposed to properly calling the explicit companion object's apply method (the one with the ignoreMe defaulted parameter).
Thank you for looking at this.
package org.public_domain
import scala.util.Try
object WorkSheetCaseClassCompanionObject {
println("Welcome to the Scala worksheet")
//
type ZipCodeParameters = (String, Option[String])
object ZipCode extends PartialFunction[ZipCodeParameters, ZipCode] {
//def apply(zip5: String, plusZip4: Option[String]): ZipCode = //not allowed - error "method apply defined twice"
def apply(zip5: String, plusZip4: Option[String], ignoreMe: Boolean = false): ZipCode =
if (isDefinedAt((zip5, plusZip4)))
new ZipCode(zip5, plusZip4)
else
throw new IllegalStateException(s"isDefinedAt failed for zip5 [$zip5] and zip4 [${plusZip4.getOrElse("<None>")}]")
override def apply(zipCodeParameters: ZipCodeParameters): ZipCode =
//apply(zipCodeParameters._1, zipCodeParameters._2) //calls case class instructor instead of above apply
apply(zipCodeParameters._1, zipCodeParameters._2, false)
def isDefinedAt(zipCodeParameters: ZipCodeParameters): Boolean = {
val (zip5, plusZip4) =
zipCodeParameters
(
"""^\d{5}$""".r.findFirstIn(zip5).nonEmpty
&& (plusZip4 match {
case Some(plusZip4Get) =>
"""^\d{4}$""".r.findFirstIn(plusZip4Get).nonEmpty
case None => true
})
)
}
}
case class ZipCode private[ZipCode] (zip5: String, plusZip4: Option[String])
//
//correct: won't compile as the new operator is not available
//val zipCodeNewApplyGood1 = Try(new ZipCode("75039", None))
//val zipCodeNewApplyGood2 = Try(new ZipCode("75039", Some("3300")))
//val zipCodeNewApplyBad1 = Try(new ZipCode("75039x", None))
//val zipCodeNewApplyBad2 = Try(new ZipCode("75039x", Some("3300")))
//val zipCodeNewApplyBad3 = Try(new ZipCode("75039", Some("3300x")))
//val zipCodeNewApplyBad4 = Try(new ZipCode("75039x", Some("3300x")))
//incorrect: appears to compile as though the case class apply method is available, but should instead call the apply in the explicit companion object
val zipCodeApplyGood1 = Try(ZipCode("75039", None))
val zipCodeApplyGood2 = Try(ZipCode("75039", Some("3300")))
val zipCodeApplyBad1_WRONG = Try(ZipCode("75039x", None))
val zipCodeApplyBad2_WRONG = Try(ZipCode("75039x", Some("3300")))
val zipCodeApplyBad3_WRONG = Try(ZipCode("75039", Some("3300x")))
val zipCodeApplyBad4_WRONG = Try(ZipCode("75039x", Some("3300x")))
val zipCodeExplicitApplyGood1 = Try(ZipCode.apply("75039", None))
val zipCodeExplicitApplyGood2 = Try(ZipCode.apply("75039", Some("3300")))
val zipCodeExplicitApplyBad1_WRONG = Try(ZipCode.apply("75039x", None))
val zipCodeExplicitApplyBad2_WRONG = Try(ZipCode.apply("75039x", Some("3300")))
val zipCodeExplicitApplyBad3_WRONG = Try(ZipCode.apply("75039", Some("3300x")))
val zipCodeExplicitApplyBad4_WRONG = Try(ZipCode.apply("75039x", Some("3300x")))
//correct: appears to compile and point to the proper apply in the explicit companion object
val zipCodeApplyFakeBooleanGood1 = Try(ZipCode("75039", None, ignoreMe = false))
val zipCodeApplyFakeBooleanGood2 = Try(ZipCode("75039", Some("3300"), ignoreMe = false))
val zipCodeApplyFakeBooleanBad1 = Try(ZipCode("75039x", None, ignoreMe = false))
val zipCodeApplyFakeBooleanBad2 = Try(ZipCode("75039x", Some("3300"), ignoreMe = false))
val zipCodeApplyFakeBooleanBad3 = Try(ZipCode("75039", Some("3300x"), ignoreMe = false))
val zipCodeApplyFakeBooleanBad4 = Try(ZipCode("75039x", Some("3300x"), ignoreMe = false))
val zipCodeFakeBooleanExplicitApplyGood1 = Try(ZipCode.apply("75039", None, ignoreMe = false))
val zipCodeFakeBooleanExplicitApplyGood2 = Try(ZipCode.apply("75039", Some("3300"), ignoreMe = false))
val zipCodeFakeBooleanExplicitApplyBad1 = Try(ZipCode.apply("75039x", None, ignoreMe = false))
val zipCodeFakeBooleanExplicitApplyBad2 = Try(ZipCode.apply("75039x", Some("3300"), ignoreMe = false))
val zipCodeFakeBooleanExplicitApplyBad3 = Try(ZipCode.apply("75039", Some("3300x"), ignoreMe = false))
val zipCodeFakeBooleanExplicitApplyBad4 = Try(ZipCode.apply("75039x", Some("3300x"), ignoreMe = false))
val tupleGood1 = ("75039", None)
val tupleGood2 = ("75039", Some("3300"))
val tupleBad1 = ("75039x", None)
val tupleBad2 = ("75039x", Some("3300"))
val tupleBad3 = ("75039", Some("3300x"))
val tupleBad4 = ("75039x", Some("3300x"))
val isDefinedAtGood1 = ZipCode.isDefinedAt(tupleGood1)
val isDefinedAtGood2 = ZipCode.isDefinedAt(tupleGood2)
val isDefinedAtBad1 = ZipCode.isDefinedAt(tupleBad1)
val isDefinedAtBad2 = ZipCode.isDefinedAt(tupleBad2)
val isDefinedAtBad3 = ZipCode.isDefinedAt(tupleBad3)
val isDefinedAtBad4 = ZipCode.isDefinedAt(tupleBad4)
val zipCodeApplyTupleGood1 = Try(ZipCode(tupleGood1))
val zipCodeApplyTupleGood2 = Try(ZipCode(tupleGood2))
val zipCodeApplyTupleBad1 = Try(ZipCode(tupleBad1))
val zipCodeApplyTupleBad2 = Try(ZipCode(tupleBad2))
val zipCodeApplyTupleBad3 = Try(ZipCode(tupleBad3))
val zipCodeApplyTupleBad4 = Try(ZipCode(tupleBad4))
val zipCodeExplicitApplyTupleGood1 = Try(ZipCode.apply(tupleGood1))
val zipCodeExplicitApplyTupleGood2 = Try(ZipCode.apply(tupleGood2))
val zipCodeExplicitApplyTupleBad1 = Try(ZipCode.apply(tupleBad1))
val zipCodeExplicitApplyTupleBad2 = Try(ZipCode.apply(tupleBad2))
val zipCodeExplicitApplyTupleBad3 = Try(ZipCode.apply(tupleBad3))
val zipCodeExplicitApplyTupleBad4 = Try(ZipCode.apply(tupleBad4))
//
println("bye")
}
Thank you for looking at this.
Leave a comment
This is the result of a combination of the way we modify the code to perform the execution (basically wrapped in a function) and a likely bug in the compiler (SI-8821).
There is a temporary workaround, because of a bug in the worksheet itself ([[#194]]).
If you remove the
There is a temporary workaround, because of a bug in the worksheet itself ([[#194]]).
If you remove the
println
at the top of the worksheet code, the code correctly fails. But, as it is an error reported late in the compilation, so you are hitting a different bug where those errors are not correctly displayed. They just blink.
No file chosen
You have an empty file field. Please select or remove it.
Name | Size |
---|