Friday, August 28, 2009

Apply-update methods

The apply and update methods have special meaning in Scala. They allow a developer to define semantics like java array access for an arbitrary class. For example:
  1. scala>class Phonebook {
  2.      |  val numbers = scala.collection.mutable.Map[String,String]()
  3.      | def apply(name:String):String = numbers(name)
  4.      | def update(name:String, number:String) = numbers(name) = number
  5.      | }
  6. defined class Phonebook
  7. scala>val book = new Phonebook() 
  8. book: Phonebook = Phonebook@1e406b09
  9. scala> book("jesse") = "123 456 7890"
  10. scala> println (book("jesse"))
  11. 123 456 7890

As you can see you can invoke the apply method in a similar way that [] are used on arrays in Java. When you call 'obj(param)' the call is translated by the compiler to: 'obj.apply(param)'. As such apply can have any number of arguments.

Similarly 'obj(param) = value' is compiled to 'obj.update(param,value)'. Again the update method can have as many arguments as you wish. However only the last argument is treated as a value. So:
  1. scala>class Echo {
  2.      | def update(n:String, n2:String, n3:String ) = println(n,n2,n3)
  3.      | }
  4. defined class Echo
  5. scala>val e = new Echo()
  6. e: Echo = Echo@2fa847df
  7. scala> e("hello", "hi") = "bonjour"
  8. (hello,hi,bonjour)
  9. scala> e("hello") = ("salut","bonjour")
  10. :7: error: wrong number of arguments for method update: (String,String,String)Unit
  11.        e("hello") = ("salut","bonjour")
  12.                   ^

This makes sense because if apply has many arguments representing the key then the same key must work for the update method for assignment. If you have many values to assign try:
  1. scala>class Phonebook {
  2.      |  val numbers = scala.collection.mutable.Map[String, (Int, Int)]()
  3.      | def apply(name:String) = numbers(name)
  4.      | def update(name:String, number:(Int,Int)) = numbers(name) = number
  5.      | }
  6. defined class Phonebook
  7. scala>val book2 = new Phonebook()
  8. book2: Phonebook = Phonebook@7a120cb3
  9. scala> book2("jesse") = (123, 4567890)
  10. scala>val (areaCode, local) = book2("jesse")
  11. areaCode: Int = 123
  12. local: Int = 4567890

No comments:

Post a Comment