azuras
azuras

Reputation: 247

Why does scala copy not preserve state from original class instance?

Seems like copy doesn't preserve any state from the original instance but just uses the base class definition to make a new instance with your new value. Anyone know why it was implemented this way?

scala> case class A(){ var y = 2 }
defined class A

scala> val a = new A()
a: A = A()

scala> a.y = 9
a.y: Int = 9

scala> a.y
res9: Int = 9

scala> val b = a.copy()
b: A = A()

scala> b.y
res10: Int = 2

Upvotes: 1

Views: 284

Answers (3)

Sebastian Celestino
Sebastian Celestino

Reputation: 1428

That is not a bug nor a mutability issue.

A case class works in a way where all its features (equals, hashcode, toString, copy, etc) are depend on its constructor parameters (some of them don't work with currying).

You will have the same problem although your variable would be a val. For example,

case class AAA() {
  val field = 1
}

val instanceA = new AAA() {
  override val field: Int = 5
}

println(instanceA.field)
// 5

println(instanceA.copy().field)
// 1

Your case class should be

case class A(y:Int = 2)

Upvotes: 3

Leo C
Leo C

Reputation: 22449

Anyone know why it was implemented this way?

This Scala-lang dialog offers good insight into why it's implemented that way. In particular, Daniel Sobral's example makes a lot of sense:

Suppose a variable should contain an unique number, such that no instances have the same number? Or suppose it points to a mutable object -- should it be shared between instances, or copied so that each instance has its own.

Upvotes: 4

Not a direct answer to your question, but this is how you could accomplish what you want in a idiomatic Scala way.

final case class A(a: Int = 2) // if a is not provided it will fallback to the default value of 2
val a = A(a = 3) // A(3)
val b = a.copy(a = 9) // A(9) - BTW, this is the same as A(a = 9)

case classes are intended for modeling immutable data objects, and the copy method is provided as a shortcut when you want to create a new object which share common state with another, so you only need to define the pieces of data you want to change.

Upvotes: 2

Related Questions