Scala Tutorials Part #17 - The Update method
Originally Posted On : 14 Jun 2017
The Update method
This is part 17 of the scala tutorial series. Check here for the full series.
Index
Introduction
update
method is a companion to the apply
method which is used to update a value of an existing type in an object. It’s usage in core language
libraries is pretty widespread as the apply method itself.
Apply and Update methods are normal functions to the user, but the compiler treats them in a special way.
Example in scala arrays
Arrays unlike java are part of collections in scala. Let’s consider the below example to understand how apply
and update
method works.
//Created using the apply method
val a = Array(12,4,5)
//A different apply method which returns the element at the given index
println(a(2))
//Updating the second index
//This is where the update method comes into play
a(2) = 20
//Printing out the changed value
println(a(2))
First thing to understand is that we can put any kind of logic inside the apply and update methods. But best practices advise developers to stick
to certain standards. apply
is generally used for applying a value(constructor in this case) and update
is used to update the array value
at a particular index. Since we are mutating the array object itself, it is generally recommended to use update method only in the case of mutable
objects/collections.
Notice that array elements are called using the ()
symbols instead of the []
as in java. This is again because array is a class and not
something native as in java.
The Array class does not have a fully formed definition of the update method because it gets generated at compile time. This will be more clear while writing our own example below.
Custom example
Let’s imagine that we have a class in which we need to store list of user names. We define the class skeleton as follows.
class UserList() {
private var list = Map(1 -> "Victor",2 -> "Selene" , 3 -> "Lucian")
}
We will see in detail what the Map
data structure is in later tutorials. For now, it can be assumed it is the equivalent of a java hash map.
Next we will define an apply method which will return the element with that key.
def apply(id : Int) = list(id)
Now we are ready to define our update method which updates/adds a value for the given key.
def update(id:Int,name:String) = {
list = list + (id -> name)
}
This adds/updates the existing key-value pair inside of the map named list
. Below is an example of how to consume this.
val a = new UserList
//Prints Victor
println(a(1))
a(1) = "Michael"
//Prints Michael
println(a(1))
a(4) = "Marcus"
//Prints Marcus - New element
println(a(4))
Multiple update methods
Let’s create an additional update
method for deeper understanding. This is slightly more complicated to visualize so we will add a
helper method in our class to print out the list.
def printContent = println(list)
Next comes our update method,
def update(name:String,replacement:String) = {
for ((k,v) <- list) {
if(v == name){
list = list + (k -> replacement)
}
}
}
The logic is pretty simple. It searches for a name which matches with the given one, then it replaces with the replacement string.
val a = new UserList
//Can be used in the place where we don't know the index
a("Lucian") = "Kraven"
//This prints out Map(1 -> Victor, 2 -> Selene, 3 -> Kraven)
a.printContent
If this approach is followed across the code base then it can lead to a much cleaner abstraction instead of having methods for each of these operations. Since this is a powerful tool, we have to keep in mind that with power comes responsibility.
Conclusion
Among the scala community, methods such as apply
and update
are often referred to as magic methods, in the sense that their true power
is not visible outside.
All these lead to functional programming, but let’s not go there yet. A bottom up approach of learning the smaller things and then trying to understand the bigger picture works really well.