Issue #6936 has been updated by naruse (Yui NARUSE).
ko1 (Koichi Sasada) wrote:
とりあえず影響が少なそうな,Float だけ frozen にしちゃうのはどうでしょ
うか.
以下のような感じですかね
diff --git a/class.c b/class.c
index 1d871fb…1df38e4 100644
— a/class.c
+++ b/class.c
@@ -1324,6 +1324,10 @@ singleton_class_of(VALUE obj)
rb_bug(“unknown immediate %p”, (void *)obj);
return klass;
}
-
else {
-
if (BUILTIN_TYPE(obj) == T_FLOAT)
-
rb_raise(rb_eTypeError, "can't define singleton");
-
}
if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) {
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index a674de8…53de6a8 100644
— a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -1129,7 +1129,7 @@ struct RBignum {
(FL_TAINT | FL_UNTRUSTED);
} while (0)
-#define OBJ_FROZEN(x) (!!FL_TEST((x), FL_FREEZE))
+#define OBJ_FROZEN(x)
(!!(FL_ABLE(x)?(RBASIC(x)->flags&(FL_FREEZE)):FLONUM_P(x)))
#define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)
#if SIZEOF_INT < SIZEOF_LONG
diff --git a/numeric.c b/numeric.c
index 58ac7ad…6a72fba 100644
— a/numeric.c
+++ b/numeric.c
@@ -621,6 +621,7 @@ rb_float_new_in_heap(double d)
OBJSETUP(flt, rb_cFloat, T_FLOAT);
flt->float_value = d;
- OBJ_FREEZE(flt);
return (VALUE)flt;
}
Feature #6936: Forbid singleton class and instance variabls for float
Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro M.)
Category: core
Target version: 2.0.0
[Feature #6763] などで議論されていた flonum が r36798 でが入ったわけですが、
- Float のオブジェクトID の仕様が変更
- flonum な float に特異メソッドが追加不可
- flonum な float に特異クラスが作成不可
- flonum な float は同じ値同士でインスタンス変数が共有される
といった非互換が存在します。
もっとも、1. は通常意識するはずのないところですし、2. は元から禁止されています。
気になるのは 3. と 4. で、これは 1.9.3 と挙動が異なるだけでなく、
32bit 環境での 2.0 や、64bit環境の flonum でない float オブジェクトとも挙動が異なります。
実際問題として実害はないような気もしますが、このような違いが極めて実装上の問題で、
Ruby 上から見えないところに存在するのは気持ち悪く感じます。
よって、以下のようにするとよいのではないでしょうか。
- flonum でない float でも特異クラスの作成を禁止
- float へのインスタンス変数作成を禁止
後者の具体的手法はいくつかあると思いますが、即値は最初から frozen にしておくとかもありかなと思っています。
話を発散させると、この話は true, false, nil, Fixnum, Symbol のような即値から、
Bignum や Time のような immutable っぽいオブジェクトにも当てはまる気がしています。