From: Yusuke ENDOH Date: 2008-04-22T23:31:12+09:00 Subject: [ruby-dev:34488] Re: coerce with Rational and Complex 遠藤です。 08/04/22 に Shin-ichiro HARA さんは書きました: > 原です。 > > > 遠藤と申します。 > > > > 以下の挙動は意図的でしょうか。 > > > > p 1.coerce(Rational(1, 2)) #=> [0.5, 1.0] > > > > 直感的には [Rational(1, 2), Rational(1, 1)] が欲しいです。 > > また、以下はどうでしょうか。 > > > > p 1.coerce(Complex(1, 1)) #=> can't convert 1+1i into Integer > > > > [Complex(1, 0), Complex(1, 1)] が欲しい気分です。 > > 原則として、coerce は、(新しい数).coerce(古い数)のみが問題なので、 > 1.coerce(Rational(1,2)) のような、(古い数).coerce(新しい数)という > パターンでは起動しないはずです。だから、変な値を返しても、例外でもかま > わないです。もちろん、それっぽい値を返しても害はないですが。いや、規約 > を破ったしるしに例外を出した方がかえっていいかな。 なるほど、そういう設計なんですね。なんとなくわかりました。 一応それっぽい値を返すパッチをいい加減に書いてみました。 Index: numeric.c =================================================================== --- numeric.c (revision 16157) +++ numeric.c (working copy) @@ -97,6 +97,8 @@ } +static int do_coerce(VALUE *x, VALUE *y, int err); + /* * call-seq: * num.coerce(numeric) => array @@ -116,9 +118,14 @@ static VALUE num_coerce(VALUE x, VALUE y) { + static int recurse = 0; if (CLASS_OF(x) == CLASS_OF(y)) return rb_assoc_new(y, x); - return rb_assoc_new(rb_Float(y), rb_Float(x)); + if (recurse) return Qnil; + recurse++; + do_coerce(&x, &y, Qtrue); + recurse--; + return rb_assoc_new(y, x); } static VALUE -- Yusuke ENDOH