Scala case class update value
Asked Answered
O

3

34

I have a case class with 2 String members. I would like to update The second member later, so first I create an instance with String and None and later I load the data to the class and would like to update the second member with some value.

How can I do it?

Obstacle answered 8/6, 2014 at 11:1 Comment(2)
Have you read about case classes? Have you tried writing something?Syphilology
Mostly duplicate of https://mcmap.net/q/117265/-how-to-clone-a-case-class-instance-and-change-just-one-field-in-scala/298389Shipyard
A
85

Define the case class so that the second member is a var:

case class Stuff(name: String, var value: Option[String])

Now you can create an instance of Stuff and modify the second value:

val s = Stuff("bashan", None)

s.value = Some("hello")

However, making case classes mutable is probably not a good idea. You should prefer working with immutable data structures. Instead of creating a mutable case class, make it immutable, and use the copy method to create a new instance with modified values. For example:

// Immutable Stuff
case class Stuff(name: String, value: Option[String])

val s1 = Stuff("bashan", None)

val s2 = s1.copy(value = Some("hello"))
// s2 is now: Stuff("bashan", Some("hello"))
Aricaarick answered 8/6, 2014 at 11:34 Comment(5)
What I find quite useful when working immutable case classes is to introduce a series of withXYZ methods for most commonly modified values. I.e. adding def withValue(v : String) : Stuff = copy(value = Some(v)) to Stuff class definition would allow you to create a modified copy in the following way s1.withValue("hello")Olin
Why is it more preferable to not mutate the parameter? Is it a design decision that is specific to Scala or is it more error prone to modify values of an object?Lawman
@Lawman Because there are a number of advantages to making objects immutable (which means: they can't change after being created). It makes code simpler and prevents concurrency problems (when multiple threads are accessing an object; it can cause difficult problems if threads are modifying objects while other threads at the same time are using these objects). It's not Scala-specific, but immutability is one of the principles of functional programming.Aricaarick
@Aricaarick appreciate the clarification. This makes a lot of sense. How would you know when to use immutable objects vs mutable objects? Or can you design with just the former in mind and never have to use mutable objects?Lawman
@Lawman Especially if you're programming in a functional style the idea is to make things immutable as much as possible, but sometimes for practical reasons you might want to have some things mutable. You can find a lot on the web about immutable vs. mutable. Scala case classes were primarily meant to be immutable.Aricaarick
K
3

Let's say your case class looks like this:

case class Data(str1: String, str2: Option[String]

First you create an instance setting the second string to None:

val d1 = Data("hello", None)

And now you create a new value by copying this object into a new one and replace the value for str2:

val d2 = d1.copy(str2=Some("I finally have a value here"))

I would also consider the possibility that your case class is not the best representation of your data. Perhaps you need one class DataWithStr2 that extends Data, and that adds another string that is always set. Or perhaps you should have two unrelated case classes, one with one string, and another with two.

Kerrison answered 21/8, 2019 at 15:17 Comment(0)
C
2

Case classes in Scala are preferably immutable. Use a regular class for what you're trying to achieve, or copy your case class object to a new one with the updated value.

Coition answered 8/6, 2014 at 11:7 Comment(1)
Case classes are not always necessarily immutable.Aricaarick

© 2022 - 2024 — McMap. All rights reserved.