Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Case class immutable still able to change the parameter values

I reviewed some code from a colleague and I came across a case class which is by default immutable.

the below case class can be changed so my question is how is this possible since case classes are immutable but in this construct i can change the case class parameters?

case class RegisterCustomerRequest(`first-name`: String,
                                   `last-name`: String,
                                   `house-details`: String,
                                   street: String,
                                   zipcode: String,
                                   city: String

    extends WcRequestData {

    def this(cardHolderData: CardHolderData,
           registrationCode: RegistrationCode,
           customerNumber: Long,
           cardDesignImageId: String) =
    this(`first-name` = cardHolderData.firstname,
         `last-name` = cardHolderData.lastname,
          street = cardHolderData.streetAndNumber,
          zipcode = cardHolderData.zipCode,
          city = cardHolderData.city,


       #   `house-details` = 
          s"${if (cardHolderData.employerName.contains("&")) 
          cardHolderData.employerName.replace("&" , " & ") else " / 
           "}${cardHolderData.employerName} ")#
    }

why can I define a def this method which can change the values of parameters. What is this construct good for is this good coding style?

like image 628
MicroLova Avatar asked Apr 08 '26 12:04

MicroLova


1 Answers

The case class RegisterCustomerRequest is still immutable however it has an auxiliary constructor def this which allows it to be constructed in a different way. For example, given

case class User(name: String)

case class Foo(name: String) {
  def this(user: User) {
    this(name = user.name)
  }
}

we can construct Foo like so

Foo("picard")

or using the auxiliary constructor

new Foo(User("picard"))

In both cases the result is an immutable object. To confirm immutability try reassigning name after construction

(new Foo(User("picard"))).name = "worf" // Error: reassignment to val 

As suggested by som-snytt, we can define apply method on companion object instead of auxiliary constructor like so

object Foo {
  def apply(user: User): Foo = Foo(user.name)
}

which enables the following construction

Foo(User("picard"))
like image 149
Mario Galic Avatar answered Apr 11 '26 01:04

Mario Galic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!