I would like to construct my domain model using immutable objects only. But I also want to use traits with val fields and move some functionality to traits. Please look at the following example:
trait Versionable {
val version = 0
def incrementVersion = copy(version=version+1)
}
Unfortunatelly such code doesn't work - copy method is unknown for trait Versionable.
I think that it would be nice to have copy method generated for every trait and class. Such method should create shallow copy of object and return it using the same type as for original object with given field modified accoring to arguments passed to method.
So in the following example:
class Customer(val name: String) extends Versionable {
def changeName(newName: String) = copy(name = newName)
}
val customer = new Customer("Scot")
customer.changeName("McDonnald")
should return an object instance Customer(version = 0, name = "McDonnald")
and
customer.incrementVersion
should also return an object instance Customer(version = 1, name = "Scot")
As far as I know current lack of such functionality in Scala doesn't allow to use immutable classes and traits without polluting class constructor with trait fields. In my example I don't want to introduce parameter named version to Customer class because functionality of version handling I want to have encapsulated in Versionable trait.
I know functionality of copy method in case classes and ability to write own copy method in class using default parameters - but I think that this functionality doesn't solve my problem because it is not possible to use such copy method in traits. Another drawback of existing functionality is that parent class using copy method returns parent class and not class of object that is actually copied.
My questions:
1) do you have idea how to handle above example in elegant way. I'm quite new to Scala so maybe there is good solution already. In my opinion elegant solutions should have following features:
should not use reflection
should not use serialization
should be fast
should be verifiable in compile time
2) what do you think about writing compiler plugin to generate code for copy method for my above example? Is it possible to do that using compiler plugin? Do you have any examples or tips how to do that?
copy
method such as you describe? Case classes cannot (technically, should not) derive from other case classes. In particular, the derived case class will inherit the super-(case)-class'scopy
method. – Iolite