Reputation: 1543
If in a Java class there is some logic or data-cleanup in the setter of a member, what is the correct and generally agreed upon approach to do the same for a Scala case-class?
Assertions? Implementing your own apply method?
Upvotes: 0
Views: 806
Reputation: 2586
One option is to use a def
or a lazy val
for getting the transformed value. E.g.
case class PostalCode(value: String) {
lazy val clean: String = value.replaceAll(" ","").toUpperCase
}
Another option, if you do not want the original value hanging around, and/or you want to throw an exception or otherwise fail for bad input:
case class PostalCode(value: String)
case object PostalCode {
def parse(s: String): Option[PostalCode] = try {
Some(PostalCode(someThrowingLogic(s)))
}
catch {
case e: Exception => None
}
def clean(s: String): PostalCode = PostalCode(s.replaceAll(" ","").toUpperCase)
}
This leaves the user still able to use the normal constructor instead of PostalCode.parse
or PostalCode.clean
. Here is another option;
trait PostalCode {
def value: String
}
case object PostalCode {
private case class PCImpl(value: String) extends PostalCode
def apply(v: String): PostalCode = v.replaceAll(" ","") match {
case s if s.length == 6 =>
PCImpl(s.toUpperCase)
case _ =>
throw new IllegalArgumentException(v + " is not a valid postal code.")
}
Upvotes: 1