Scalaでは値を取り出すときはapplyメソッドが、値を設定するときはupdateメソッドが呼び出されるらしい。
それらに任意の処理を設定するサンプル。
properties.scala | The Scala Programming Language
package sample.snippet /** Illustrate the use of custom 'apply/update' methods. */ object properties { /** A mutable propert whose getter and setter may be customized. */ case class Property[T](init: T) { private var value: T = init private var setter: T => T = identity[T] private var getter: T => T = identity[T] /** Retrieve the value held in this property. */ def apply(): T = getter(value) /** Update the value held in this property, through the setter. */ def update(newValue: T) = value = setter(newValue) /** Change the getter. */ def get(newGetter: T => T) = { getter = newGetter; this } /** Change the setter. */ def set(newSetter: T => T) = { setter = newSetter; this } } class User { // Create a property with custom getter and setter val firstname = Property("") .get{ v => v.toUpperCase() } .set { v => "Mr. " + v } val lastname = Property("<noname>") /** Scala provides syntactic sugar for calling 'apply'. * Simply adding a list of arguments between parenthesis * (int this case, an empty list) is translated to a call * to 'apply' woth those argyments. */ override def toString() = firstname() + " " + lastname() } def main(args: Array[String]) { val user1 = new User // Syntactic sugar for 'update': an assignment is translated to a call to method 'update' user1.firstname() = "Robert" val user2 = new User user2.firstname() = "bob" user2.lastname() = "KUZ" println("user1: " + user1) println("user2: " + user2) } }
Propertyクラスから見ていくと、valueが実際の値。
setterもgetterもT型の引数をもらいT型の値を返す関数。
デフォルトはPredefクラスに定義されてるidentityメソッド。
implicit def identity[A](x: A): A = x
そのままxを返すだけ。何の処理もしてない。
で、applyはgetterを呼び出し、updateはsetterを呼び出す。
get,setでgetter,setterの関数を変更する。
Userクラスでは、firstnameはgetすると大文字で返す関数。setは文頭にMr.をつけた値を返す関数。
setで値を返すけど、updateメソッドを見るとわかるように、setter関数の戻り値をvalueに代入するからね。
toStringメソッドをオーバーライドしてるけど、要は変数名のうしろに()をつけるとapply/updateが呼び出されますよーということ。
そういうシンタックスシュガーだって。
引数があれば()の中に書けばいいと。
ん?じゃあこれを
user2.firstname() = "bob"
こう書いてもいいってこと?
user2.firstname("bob")
コンパイルエラー。。。
「wrong number of arguments for method apply」。
値を更新してるからupdateメソッドじゃないの??
コメントには「Syntactic sugar for 'update': an assignment is translated to a call to method 'update'」ってあるし。
でも、firstname("bob")のようなシンタックスシュガーはないってことかな。
実行結果。
user1: MR. ROBERT <noname> user2: MR. BOB KUZ