Ruby のメソッド引数の初期値は実行時に評価される
こないだ書いたように、lib/resolv.rb の作業をしていたのだけど、そのとき気づいたのが、Ruby のメソッド引数の初期値は実行時に評価されるということ。
今までなんとなく def の実行時(スクリプトの読み込み時)に評価されると思い込んでいたよ。C 側で実装するときのことを思い出してみれば当たり前なのだけど、なぜ気づかなかったのだろう?
いくつか例を
def sender(msg, data, queue, host=@host, port=@port)
インスタンス変数を初期値に
def initialize(id = (@@identifier += 1) & 0xffff)
クラス変数に1加算して、4バイトに。最初見たときナニゴトかと思った。式が書けるのだから、演算したっていいわけだ。
で、「他にはどんなのがあるだろう?」と Google Code Searchで探してみたら、「これはうまいなあ」というのを見つけた。net/ftp.rb ね。
def put(localfile, remotefile = File.basename(localfile),
blocksize = DEFAULT_BLOCKSIZE, &block)
1番目の localfile が先に評価されるから、省略時にその値を利用して File.basename で初期値を設定できる。勉強になるなあ。