Reputation: 965
I am using Scala 2.11.1 with akka 2.3.8
let say I have a class
case class Person(firstName : String, var lastName : String,var age : Int, doB : DateTime)
I am confused that should I use val
for all the attribute or should i go for the var
for the attributes that can be mutated in the future
please guide me what is the better approach to do it keeping in mind that i am using the object of such classes in actors message passing
Edit :
Also please tell me if a thread comes and changes an attribute of the class, would this be an in place mutation or a new object will be formed with the changed attribute?
Upvotes: 0
Views: 174
Reputation: 5049
First things first, I think you should not have both age
and doB
in this case. You're asking for trouble. Use the doB
only and calculate the age when you need it, it's cheap. The doB
is constant, the age changes, for starters. This is a domain thing, not related to Scala or Akka. Also, since this is a message, a Data Transfer Object, it should not have the need to mutate, it does not have a long lifetime, IMHO.
This probably solves your concrete issue, but in general case, if you really need mutation, than yes, make it a var
. But yet again, consider if you need it. If you have the need to change it, then make a setter which creates a new, also immutable object, with the same attributes as the previous, but with that one attribute changed.
Edit:
Since you added details to you question, maybe you need some additional explanation.
If you are using Akka properly, than you should not worry about threads changing objects. Each actor is a separate thread, and it has it's own isolated scope. Which means that a message sent from ActorA
to ActorB
is a copy. Mutating the message in ActorB
will not change the any data in scope of ActorA
. Remember, actors should react only according to the messages they receive. Activity of one, should not interfere with another, considering they do not share a resource such as database, which is another story.
@ccheneson gave a nice explanation how to create a new immutable object from an existing one by editing some of its attributes. When using the copy
method, you get two objects, the original one you copied from which is unchanged, and the new, modified. If you do, for example:
val p1 = Person("Aleksandar","Stojadinovic",25,"1970-01-01") //mocking the date, ignoring I advised you not to use age, and look what I was allowed to do ^.^
p1.age=28
println(p1.age) //outputs 28
Your p1
is now changed. If you are using regular threading, instead of Akka, you might get into trouble with thread synchronization and the Reader-Writer problem
You should not run threads within an actor, if that is what are you trying.
Upvotes: 2
Reputation: 49410
Aleksandar Stojadinovic has a good point about age
and doB
.
I will just add that you can keep all your attributes as val
and if you need to change an attribute value, use the copy
method (provided for free with your case class
) and change the attribute you want. copy
will return a new Person
object with your attribute updated
scala> case class Person(firstname: String, lastname:String)
defined class Person
scala> val p1 = Person("John", "Doe")
p1: Person = Person(John,Doe)
scala> val p2 = p1.copy(lastname = "Wayne")
p2: Person = Person(John,Wayne)
Upvotes: 1