読者です 読者をやめる 読者になる 読者になる

Fight the Future

何かを始めたら、半分成功したのと同じ

ScalaのAdvanced Exampleを写経する(11)-property

の謎が解けた。
timeofday.scala | The Scala Programming Language

package sample.snippet

object timeofday {

  class DateException extends Exception
  
  /** Simulating properties in Scala.
   */
  class TimeOfDayVar {
    
    private var h: Int = 0
    private var m: Int = 0
    private var s: Int = 0
    
    def hours = h
    
    /** A method 'ident_=' is a setter for 'ident'.
     * 'code.ident = ...' will be translated to a call to 'ident_='
     */
    def hours_= (h: Int) = { 
      if (0 <= h && h < 24)
        this.h = h
      else
          throw new DateException
    }
    
    def minute = m
    def minute_= (m: Int) = {
      if (0 <= m && m < 60) 
        this.m = m
      else
          throw new DateException
    }

    def second = s
    def second_= (s: Int) = {
      if (0 <= s && s < 60)
        this.s = s
      else
          throw new DateException
    }
  }
    def main(args: Array[String]) {
      val d = new TimeOfDayVar
      d.hours = 8;
      d.minute = 30
      d.second = 0
      
      println(d.hours)
      println(d.minute)
      println(d.second)
      
      d.hours = 25 // throws a DateException
    }  
}

プロパティで「プロパティ名_=」というメソッドを作ればそれがセッターになる。
「プロパティ名 = 値」は「プロパティ名_=(値)」メソッドの呼び出しと解釈される。
つまり

d.hours = 8;

d.hours_=(8)

と解釈される。


このときの「=」には代入の意味はなく、ただの記号だ。
だから

    def hours_= (h: Int) = { 

    def hours_ = (h: Int) = { 

と書くとコンパイルエラーとなる。


実行結果。

8
30
Exception in thread "main" sample.snippet.timeofday$DateException
	at sample.snippet.timeofday$TimeOfDayVar.hours_$eq(timeofday.scala:24)
	at sample.snippet.timeofday$.main(timeofday.scala:53)
	at sample.snippet.timeofday.main(timeofday.scala)
0