ruby-trunk-changes r29548 - r29555

だいぶ慣れてきたので MacRuby か Rubinius のコミットも読み始めようかなーなどと思ってみています。さすがに日刊の changes を2つやるのはむつかしいので、とりあえず読むだけ。

nobu:r29548 2010-10-21 23:47:13 +0900

dir.c で無駄な自動変数の使い方をしていたところを削ってすっきり。

nobu:r29549 2010-10-21 23:52:02 +0900

r29543 の再修正みたいです。返り値が VALUE の関数で return; って書いてコンパイル通るんですね、警告は出ますが。

nobu:r29550 2010-10-21 23:56:55 +0900

もうひとつ、関数ポインタとユーザデータポインタを VALUE の配列にしたもの(VALUE *)をさらに VALUE にキャストして渡す……みたいなことをしていたところをきちんと構造体を宣言して型がこんがらがらないようにしています。

ko1:r29551 2010-10-22 00:03:56 +0900

もうひとつ、変数の宣言がブロックの先頭じゃないところにあったので移動。INIT_GC_PROF_PARAMS というマクロは変数宣言を含んでます。MRI には変数宣言を含むマクロが時々ありますから注意が必要ですね。

svn:r29552 2010-10-22 00:03:58 +0900

version.h の日付変更。

ryan:r29553 2010-10-22 06:15:06 +0900

Test::Unit::Assertions#assert の省略可能引数には省略されたことを検出するためにこんなトリッキーなことをしていました。

  def (test, msg = (nomsg = true; nil))
   ...

これは第2引数が省略されたら nil で初期化されるのですが、その時 nomsg = true も評価されるのでローカル変数 nomsg に引数が省略されたかどうかが入るわけですね。
それをこんなふうに変更しています。

  UNASSIGNED = Object.new
  def assert(test, msg = UNASSIGNED)
    msg = nil if msg == UNASSIGNED

UNASSINGED には Object のインスタンスを格納しているので……あれ、これちょっと変ですね。元のコードは msg に nil が明示的に引数に渡されたのと、省略されたのを区別したくてああしていたのに区別されていませんよ。と思ったら引き続きこのコミットの再修正が入ってました。
あと、UNASSINED に Object のインスタンスを入れているのは、確実にこの値と一致する時だけを検出したいからなので msg == UNASSIGNED ではなくて UNASSIGNED == msg にしないといけませんよね。レシーバによっては真になってしまうかもしれませんから。

naruse:r29554 2010-10-22 14:10:40 +0900

msg が nil の時の条件を追加しています。が、これでも不完全で、nil が明示的に渡されたのか省略された結果 nil が入ったのかを区別しないといけないです。

nobu:r29555 2010-10-22 14:50:17 +0900

で、再度修正。case 文を使って UNASSIGNED の時は別途 caller の調整をスキップさせつつ msg を nil に初期化しなおしています。
case 文だと when の右辺値とは

case msg
when UNASSIGNED
...

の場合 UNASSIGNED === msg で比較するので大丈夫ですね。Object#=== は Object#== と同一なので。