Coerce via aliased methods

ruby-dev:33095 にレスが付かずに放置されてるので、RHGの逆襲のあと、笹田さんに聞いてみた。

問題

うん。問題は数値二項演算メソッドがcoercingを必要とするときの処理が全部、rb_num_coerceやrb_big_coerceに委譲されてるっていうことなんだ。rb_xxx_coerceは引数に演算の名前を取らない。だから、委譲された演算本体の処理を行うためには、スタックフレームから呼び出し元の演算名を取り出さないといけない。このスタックフレームに積まれてる名前が、違ってる。Ruby 1.8ではaliasされたメソッドは「定義時の名前」が積まれていた。YARVでは「aliasされた名前」が積まれている。

笹田さんに聞いてみたら、これは意図した仕様じゃないみたい。でも、直そうと思ったらYARVの深いところをいじらなくちゃいけないので大変らしい。YARVでは今、AST段階で使ってたRNodeを使い回すのをやめて、バイトコード実行時には独自の構造体を使うように変更中らしい。これと絡むとか。

私の都合

私がcoerce問題を見つけたのはrationalのテストケースを書いてたとき。rationalを組み込み化するにあたって、とりあえず今のrationalの仕様を定義したい。だから、今のrationalには100%テストにパスしてもらいたい。でも、coerce問題のせいで 1 ** Rational(1, 2) は動作しない。

方針

するってーと、どうすれば良いんだ? Fixnum, Bignum, Floatの二項演算メソッド、これのcoerce呼び出し部分を変えてやればとりあえずrationalは動くようになる。でも、そのためだけにFixnumとかをいじるのか? でもなー、とりあえずこれはtrunkにおいてcoerceメカニズムがうまく働いてないわけで、Fixnumとかのバグではあるわけだよね。直しちゃって良いんだろうか。でも、rb_num_coerceのシグネチャは拡張ライブラリ向けAPIだから変えられないぞ。組み込みの二項演算は何かrb_num_coerce以外の静的関数呼べば直るとして、でもYARVが直らないとこのシグネチャを保ったままrb_num_coerceは動作するようにならないぞ。

そもそも、aliasされたメソッドの中でcoerceしたら、変換された値たちをエイリアスと定義時の名前と、どちらのメソッドに掛けるべきだろう。どっちがRubyとして自然なんだろう。「驚き最小の法則」。これはRubyの世界観の話だからMatzの判断を仰ぎたいんだけど、返事がない。ただの屍のようだ。笹田さんによれば「なんか最近忙しそう」ってことだから、ちょっと待つか。