alt-f4
alt-f4

Reputation: 2306

How to construct case classes conditionally based on their parameters?

I am currently trying to create case classes that are constructed differently based on the inputs of their parameters. As a real world use-case, let's say we are constructing a case class that contains sensitive information. So everytime the case class contains data from a user, we need to hash their phone number, otherwise construct the case class as normal. If that did not make much sense, I have created a lighter example to illustrate what I am trying to do.

Let's say we are creating a case class that does not accept a sad cow like:

case class HappyCow(name: String, feeling: String)

I tried making the case class construction conditional by defining an apply method:

case class HappyCow(name: String, feeling: String) {
  def apply(name: String, feeling: String): HappyCow =
    if (feeling == "sad") HappyCow(name, "Happy")
    else HappyCow(name, feeling)
}

However testing if my solution works results in:

 val cow1 = HappyCow("Moowy", "excited")
 val cow2 = HappyCow("MooMoo", "sad")

 println(cow1) // HappyCow(Moowy,excited)
 println(cow2) // HappyCow(MooMoo,sad)
 println(cow2.feeling) // sad

I expected cow2.feeling to be "Happy"

Upvotes: 1

Views: 853

Answers (1)

Dmytro Mitin
Dmytro Mitin

Reputation: 51658

apply should be a method of companion object, not case class.

Also inside definition of apply replace HappyCow(name, "Happy")... with new HappyCow(name, "Happy")..., otherwise it's infinite recursion.

case class HappyCow(name: String, feeling: String)

object HappyCow {
  def apply(name: String, feeling: String): HappyCow =
    if (feeling == "sad") new HappyCow(name, "Happy")
    else new HappyCow(name, feeling)
}

val cow1 = HappyCow("Moowy", "excited")
val cow2 = HappyCow("MooMoo", "sad")

println(cow1) // HappyCow(Moowy,excited)
println(cow2) // HappyCow(MooMoo,Happy)
println(cow2.feeling) // Happy

Upvotes: 4

Related Questions