[#41918] [Feature #3647] Array#sample(n, replace=false) — Kenta Murata <redmine@...>

Feature #3647: Array#sample(n, replace=false)

11 messages 2010/08/03

[#41966] [Bug #3673] PTY.getpty with IO.pipe doesn't finish on FreeBSD — Yui NARUSE <redmine@...>

Bug #3673: PTY.getpty with IO.pipe doesn't finish on FreeBSD

9 messages 2010/08/10

[#41969] [Feature #3675] String#prepend, String#>> — Sora Harakami <redmine@...>

Feature #3675: String#prepend, String#>>

15 messages 2010/08/10
[#41976] Re: [Feature #3675] String#prepend, String#>> — Yukihiro Matsumoto <matz@...> 2010/08/10

まつもと ゆきひろです

[#41974] Re: [ruby-cvs:36157] Ruby:r28955 (trunk): * complex.c (nucomp_to_[ifr]): don't allow complex with in-exact — Yukihiro Matsumoto <matz@...>

まつもと ゆきひろです

7 messages 2010/08/10

[#42003] WEBrickに関するセキュリティ修正 (CVE-2010-0541) — Hideki Yamane <henrich@...>

12 messages 2010/08/11

[#42090] Math::atan2(0, 0) on ruby 1.9.2 — KUBO Takehiro <kubo@...>

久保です。

18 messages 2010/08/22
[#42092] Re: Math::atan2(0, 0) on ruby 1.9.2 — Kenta Murata <muraken@...> 2010/08/22

むらたです。

[#42166] Ruby'sライセンスの、BSDLとのデュアルライセンスへの変更 — "NARUSE, Yui" <naruse@...>

Ruby's ライセンスは BSDL と Ruby's のデュアルライセンスになります。

14 messages 2010/08/31

[ruby-dev:42039] [Bug #3696] Fwd: [ruby-list:47272] case when 整数と実数の比較 (ruby 1.9)

From: Ikuo KOBORI <redmine@...>
Date: 2010-08-15 12:09:52 UTC
List: ruby-dev #42039
チケット #3696 が更新されました。 (by Ikuo KOBORI)


小堀といいます。

以下のようにして修正できましたので、報告します。
whenにあらわれるのがすべて定数のとき、整数だろうと浮動小数点数であろうとハッシュテーブルに登録しています。
すると小数と整数の組み合わせでは、比較しても一致しなくなってしまいます(1 と 1.0 の場合など)。
なので小数を整数に丸めても精度が落ちないときは、変換してからテーブルに登録するようにしました。case に小数があらわれたときも同様です。

その他の場合にはテーブルを作ったとしても、入る物と型が一致していないと値は同じになることはないので、それぞれ特別扱いにしました。こうすることで case に独自のオブジェクトが渡されたときに対応できます。例えばつぎのような場合です。

class C
  def ==(other)
    true
  end
end

obj = C.new
case obj
when 1
  p "OK"
else
  p "NG"
end

このときにも "OK" と出力されるようになります。

diff --git a/compile.c b/compile.c
index 2fd804c..f5f3508 100644
--- a/compile.c
+++ b/compile.c
@@ -2302,14 +2302,22 @@ case_when_optimizable_literal(NODE * node)
 {
     switch (nd_type(node)) {
       case NODE_LIT: {
-	VALUE v = node->nd_lit;
-	if (SYMBOL_P(v) || rb_obj_is_kind_of(v, rb_cNumeric)) {
-	    return v;
-	}
-	break;
+        VALUE v = node->nd_lit;
+        if ((SYMBOL_P(v) || rb_obj_is_kind_of(v, rb_cInteger))) {
+            return v;
+        }
+        if (rb_obj_is_kind_of(v, rb_cFloat)) {
+            if (RFLOAT_VALUE(v) == (long long)RFLOAT_VALUE(v)) {
+                return rb_funcall(v, rb_intern("to_i") , 0);
+            }
+            else {
+                return v;
+            }
+        }
+        break;
       }
       case NODE_STR:
-	return node->nd_lit;
+        return node->nd_lit;
     }
     return Qfalse;
 }
diff --git a/insns.def b/insns.def
index fcd97ae..bcf5aa8 100644
--- a/insns.def
+++ b/insns.def
@@ -1260,28 +1260,40 @@ opt_case_dispatch
 (..., VALUE key)
 () // inc += -1;
 {
-    if (BASIC_OP_UNREDEFINED_P(BOP_EQQ)) {
-	VALUE val;
-	if (st_lookup(RHASH_TBL(hash), key, &val)) {
-	    JUMP(FIX2INT(val));
-	}
-	else {
-	    JUMP(else_offset);
-	}
-    }
-    else {
-	struct opt_case_dispatch_i_arg arg;
+    struct opt_case_dispatch_i_arg arg;
 
-	arg.obj = key;
-	arg.label = -1;
-	st_foreach(RHASH_TBL(hash), opt_case_dispatch_i, (st_data_t)&arg);
-
-	if (arg.label != -1) {
-	    JUMP(arg.label);
-	}
-	else {
-	    JUMP(else_offset);
-	}
+    switch(TYPE(key))
+    {
+      case T_FLOAT:
+          if (RFLOAT_VALUE(key) == (long long)RFLOAT_VALUE(key)) {
+              key = rb_funcall(key, rb_intern("to_i") , 0);
+          }
+      case T_SYMBOL: /* fall through */
+      case T_FIXNUM:
+      case T_BIGNUM:
+      case T_STRING:
+        if (BASIC_OP_UNREDEFINED_P(BOP_EQQ)) {
+            VALUE val;
+            if (st_lookup(RHASH_TBL(hash), key, &val)) {
+                JUMP(FIX2INT(val));
+            }
+            else {
+                JUMP(else_offset);
+            }
+            break;
+        }
+      default: /* fall through (else) */
+          arg.obj = key;
+          arg.label = -1;
+          st_foreach(RHASH_TBL(hash), opt_case_dispatch_i, (st_data_t)&arg);
+
+          if (arg.label != -1) {
+              JUMP(arg.label);
+          }
+          else {
+              JUMP(else_offset);
+          }
+          break;
     }
 }
 
----------------------------------------
http://redmine.ruby-lang.org/issues/show/3696

----------------------------------------
http://redmine.ruby-lang.org

In This Thread