Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'copy' for non-case classes?

Tags:

When I'm designing immutable objects, case classes are incredibly handy because of the auto-generated copy method.

But case classes have their own problems: they shouldn't be inherited from and they give you an extractor even if you don't want one.

So sometimes I have to use a garden-variety Scala class. The problem is that then I have to write my own immutable API, which can be pretty repetitive:

class Debt(principalBalance: Double, name: String, endDate: LocalDate) {
  def withNewPrincipalBalance(bal: Double) = new Debt(bal, name, endDate)
}

Is there a more scalable way to do this? Is there a compiler plugin I can use?

like image 884
Bill Avatar asked Jul 09 '11 20:07

Bill


People also ask

What does case class mean?

A case class has all of the functionality of a regular class, and more. When the compiler sees the case keyword in front of a class , it generates code for you, with the following benefits: Case class constructor parameters are public val fields by default, so accessor methods are generated for each parameter.

For which kind of data should you use a case class?

Case classes are good for modeling immutable data. In the next step of the tour, we'll see how they are useful in pattern matching.

What are case classes in spark?

Delta Lake with Apache Spark using Scala The case class defines the schema of the table. The names of the arguments to the case class are read using reflection and they become the names of the columns. Case classes can also be nested or contain complex types such as Sequences or Arrays.

Can case class have methods?

case classes automatically have equality and nice toString methods based on the constructor arguments. case classes can have methods just like normal classes.


1 Answers

I don't know about a compiler plugin, but you can define a copy method just like the one generated in case classes using named arguments in combination with default arguments.

class Debt(principalBalance: Double, name: String, endDate: LocalDate) {
  def copy(principalBalance: Double = principalBalance,
           name: String = name,
           endDate: LocalDate = endDate) = new Debt(principalBalance, name, endDate)
}

This is not as repetitive as separate methods for each property (withNewPrincipalBalance) and makes it possible to disallow changes of certain values (for example the creation date).

like image 88
kassens Avatar answered Oct 21 '22 20:10

kassens