Understanding this Mutable Recursive Function using the uJson library

108 views Asked by At

I am trying to implement an insert function using the ujson library:

Here is my attempt:

import ujson.{Obj, Value}
import upickle.default._

object Example extends App {
  def r = transform(
    List(Map(
      "a" -> Map("b" -> Obj("c" -> List(1,2,3), "d" -> List(2,4,6))), 
      "e" -> Map("f" -> Obj("g" -> List(1,2,3)))))
  ).to(Value)

  def insert(j: ujson.Value, k: String, v: ujson.Value): Unit = j match {
    case a: ujson.Arr => a.arr.foreach(e => insert(e, k, v))
    case o: ujson.Obj =>
    if (o.obj.keySet contains k)  o.obj(k) = v
    else o.obj.values.foreach(e => insert(e, k, v))
    case _ => Nil
  }

  println(r)
  insert(r, "b", transform(None).to(Value))
  println(r)
}

However, this gives me output that is unchanged:

[{"a":{"b":{"c":[1,2,3],"d":[2,4,6]}},"e":{"f":{"g":[1,2,3]}}}]
[{"a":{"b":{"c":[1,2,3],"d":[2,4,6]}},"e":{"f":{"g":[1,2,3]}}}]

Given that the Value type is mutable, why does this not mutate and update the key, k, with value v for json value object r?

1

There are 1 answers

1
Mateusz Kubuszok On BEST ANSWER

You are creating Value anew every time you call r so, every changes you would make to it, are dismissed.

You create one copy when you call println(r).

Then you create a separate copy with insert(r, "b", transform(None).to(Value)), mutate it and dismiss.

Then you are creating third copy with another println(r).

If you want to refer to the same object use val instead of def.