-2

Im trying to understand the following code, how the value in the variables a of case class dummy is being updated in the following code.

In the value method, I'm assigning the value of a to b , and adding new Node to b, which inturn it is reflecting the changes in a also. I don't understand how the value is a is being changed without even re-assignement.

object test {
  def main(args: Array[String]) {

    case class abc(str: String, var ele: abc)

    case class dummy(a: abc) {
      def value() = {
        var b = a
        println(s"Value of B before changing : ${b.str}") // Value of B before changing : Good
        println(s"Value of A before changing : ${a.str}") // Value of A before changing : Good
        val newObj = abc(" Morning", null)
        b.ele = newObj
        println(s"Value of A After changing : ${a.str},${a.ele.str}") // Value of A After changing : Good, Morning
        println(s"Value of B after changing : ${b.str},${b.ele.str}") // Value of B after changing : Good, Morning
      }
    }

    val testObj = dummy(abc("Good", null))
    testObj.value()
  }
}
Dinesh Vishwakarma
  • 656
  • 3
  • 13
  • 34
Guda uma shanker
  • 183
  • 1
  • 13

1 Answers1

2
var b = a

This does not make a copy.

You now have both variables pointing to the same object, and any change made to the state of b will also reflect in a.

For this (and other reasons) you are highly encouraged to avoid mutable state. If your case class did not have a var in it, it would be immutable and you can be sure that no matter who you give your a to, it will still be intact when you get it back.

(The second bad habit to shake is using null. No need for that in Scala, make the type an Option instead).

Thilo
  • 257,207
  • 101
  • 511
  • 656
  • as you have said , `var b = a` 'doesn't make a copy' is this statement valid only for case class with contains mutable fields. – Guda uma shanker Mar 09 '19 at 04:31
  • 1
    It is the same for all objects (including arrays). A `=` just assigns pointers to objects to another variable (which will then refer to the same object, not to a copy). – Thilo Mar 09 '19 at 04:37
  • I tried the same for this code `var a = 2; var b = a; b = 3; println(a,b) // (2,3) `, according to statement it should update the value in a also, but it is not doing . – Guda uma shanker Mar 09 '19 at 04:41
  • 1
    `b = 3` does not update the object that `b` is pointing to. It sets `b` to another value. That does not affect other variables (like `a`) that happen to also contain the old value. Your original code had `b.ele = newObj` (NOT `b = newObj`). That kept `b` pointing at the same object (which `a` was also looking at), but updated `ele` *inside* of that object (and thus, also `a.ele` which at that point was just another name/variable/label for the same thing). – Thilo Mar 09 '19 at 05:04
  • Read this (even though it is about Java, the same applies to Scala): https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value?noredirect=1&lq=1 It is important to understand that an object and a variable pointing to the object are not the same thing. – Thilo Mar 09 '19 at 05:05