From: Kazuhiro NISHIYAMA Date: 2010-05-26T06:58:27+09:00 Subject: [ruby-dev:41415] [Bug #3341] Random#randにTimeのRangeを渡すとSEGVする チケット #3341 が更新されました。 (by Kazuhiro NISHIYAMA) range.end - range.begin が Float なら落ちるようで ruby-trunk -e ';x=Object.new; def x.-(o);1.1;end; Random.new.rand(x..x)' でも落ちました。 random_rand で * v = range_values(vmax, &beg, &excl) が Time.now-Time.now で Float になる * (vがgenrand_real2(&rnd->mt)をかけたものになる) * RFLOAT_VALUE(rb_check_to_float(beg)); で beg が Time なので RFLOAT_VALUE(nil) になって落ちる という流れのようなので、以下のパッチのように単純に beg + v にした方が Random.new.rand(Time.at(0)..Time.now) のような使い方も出来て良いのではないでしょうか? diff --git a/random.c b/random.c index b2abca7..17cdf49 100644 --- a/random.c +++ b/random.c @@ -1074,15 +1074,7 @@ random_rand(int argc, VALUE *argv, VALUE obj) long x = FIX2LONG(beg) + FIX2LONG(v); return LONG2NUM(x); } - switch (TYPE(v)) { - case T_BIGNUM: - return rb_big_plus(v, beg); - case T_FLOAT: - RFLOAT_VALUE(v) += RFLOAT_VALUE(rb_check_to_float(beg)); - return v; - default: - return rb_funcall2(v, id_plus, 1, &beg); - } + return rb_funcall2(beg, id_plus, 1, &v); } /* ---------------------------------------- http://redmine.ruby-lang.org/issues/show/3341 ---------------------------------------- http://redmine.ruby-lang.org