Eugen
Eugen

Reputation: 1543

Correct way to have a "setter" in Scala?

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

Answers (1)

retrospectacus
retrospectacus

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

Related Questions