Forum: Ruby-dev [ruby-trunk - Feature #6936][Assigned] Forbid singleton class and instance variabls for float

9361878d459f1709feec780518946ee5?d=identicon&s=25 naruse (Yui NARUSE) (Guest)
on 2012-08-27 14:00
(Received via mailing list)
Issue #6936 has been reported by naruse (Yui NARUSE).

----------------------------------------
Feature #6936: Forbid singleton class and instance variabls for float
https://bugs.ruby-lang.org/issues/6936

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


[Feature #6763] などで議論されていた flonum が r36798 でが入ったわけですが、

1. Float のオブジェクトID の仕様が変更
2. flonum な float に特異メソッドが追加不可
3. flonum な float に特異クラスが作成不可
4. 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 っぽいオブジェクトにも当てはまる気がしています。
308cbef6e86dfc49cce3b2d4cf42aedc?d=identicon&s=25 SASADA Koichi (Guest)
on 2012-08-27 14:04
(Received via mailing list)
(2012/08/27 8:12), naruse (Yui NARUSE) wrote:
> 後者の具体的手法はいくつかあると思いますが、即値は最初から frozen にしておくとかもありかなと思っています。

 Numeric は freeze しちゃう,というのだとやり過ぎでしょうか.
02da662c083396641da96c1d32fc86ed?d=identicon&s=25 KOSAKI Motohiro (Guest)
on 2012-08-27 14:04
(Received via mailing list)
>> $B8e<T$N6qBNE*<jK!$O$$$/$D$+$"$k$H;W$$$^$9$,!"B(CM$O:G=i$+$i(B frozen
$B$K$7$F$*$/$H$+$b$"$j$+$J$H;W$C$F$$$^$9!#(B
>
> $B!!(BNumeric $B$O(B freeze $B$7$A$c$&!$$H$$$&$N$@$H$d$j2a$.$G$7$g$&$+!%(B

$B$\$/$O$"$j$@$H$*$b$&!#?t$H$$$&35G0$O@$3&$,$O$8$^$k$h$jA0$+$i$"$C$?$N$@!"%`%O%O%O%O%O$H$$$&@$3&$G$9$J(B
9361878d459f1709feec780518946ee5?d=identicon&s=25 NARUSE, Yui (Guest)
on 2012-08-27 15:35
(Received via mailing list)
(2012/08/27 17:46), KOSAKI Motohiro wrote:
>>> $B8e<T$N6qBNE*<jK!$O$$$/$D$+$"$k$H;W$$$^$9$,!"B(CM$O:G=i$+$i(B frozen
$B$K$7$F$*$/$H$+$b$"$j$+$J$H;W$C$F$$$^$9!#(B
>>
>> $B!!(BNumeric $B$O(B freeze $B$7$A$c$&!$$H$$$&$N$@$H$d$j2a$.$G$7$g$&$+!%(B
>
>
$B$\$/$O$"$j$@$H$*$b$&!#?t$H$$$&35G0$O@$3&$,$O$8$^$k$h$jA0$+$i$"$C$?$N$@!"%`%O%O%O%O%O$H$$$&@$3&$G$9$J(B

$B$=$&$G$9$M!"$=$&$9$k$HE}0l46$,=P$k$s$8$c$J$$$+$J$!$H;W$C$F$$$^$9!#(B
8cbb39dadafaf2287a83a13ee4981ec9?d=identicon&s=25 U.Nakamura (Guest)
on 2012-08-28 02:53
(Received via mailing list)
$B$3$s$K$A$O!"$J$+$`$i(B($B$&(B)$B$G$9!#(B

In message "[ruby-dev:46082] Re: [ruby-trunk - Feature #6936][Assigned]
Forbid singleton class and instance variabls for float"
    on Aug.27,2012 15:22:07, <ko1@atdot.net> wrote:
> $B!!(BNumeric $B$O(B freeze $B$7$A$c$&!$$H$$$&$N$@$H$d$j2a$.$G$7$g$&$+!%(B

+1


$B$=$l$G$O!#(B
7cca11c5257fda526eeb4b1ada28f904?d=identicon&s=25 Kenta Murata (Guest)
on 2012-08-28 15:05
(Received via mailing list)
$B$`$i$?$G$9!#(B

2012/8/28 U.Nakamura <usa@garbagecollect.jp>:
> $B$3$s$K$A$O!"$J$+$`$i(B($B$&(B)$B$G$9!#(B
>
> In message "[ruby-dev:46082] Re: [ruby-trunk - Feature #6936][Assigned] Forbid
singleton class and instance variabls for float"
>     on Aug.27,2012 15:22:07, <ko1@atdot.net> wrote:
>>$B!!(B Numeric $B$O(B freeze $B$7$A$c$&!$$H$$$&$N$@$H$d$j2a$.$G$7$g$&$+!%(B
>
> +1

$B$o$?$7$b(B +1$B!#(B

--
Kenta Murata
OpenPGP FP = 1D69 ADDE 081C 9CC2 2E54  98C1 CEFE 8AFB 6081 B062

$BK\$r=q$-$^$7$?(B!!
$B!X(BRuby $B5U0z$-%l%7%T!Y(B
http://www.amazon.co.jp/dp/4798119881/mrkn-22

E-mail: mrkn@mrkn.jp
twitter: http://twitter.com/mrkn/
blog: http://d.hatena.ne.jp/mrkn/
E4155d091a39e0d0b51991a796f2891e?d=identicon&s=25 Inaba Hiroto (Guest)
on 2012-08-29 18:55
(Received via mailing list)
$B0pMU$H?=$7$^$9!#(B
$BIt30<T(B(Perl$B20(B)$B$+$i$NCc!9$G$9!#$9$_$^$;$s!#(B

(2012/08/28 22:04), Kenta Murata wrote:
>
> $B$o$?$7$b(B +1$B!#(B

$B$3!<$f$&$N$,(B++$B$G$J$$$N$,(BRubyist$B$+!"$C$F;W$$$^$7$?!#(B
$B!J$R$g$C$H$7$F(BRuby$B3&$G$O>o<1!)(B +=1$B$8$c$J$$$s$G$9$M!#!K(B

$B$9$_$^$;$s!#(B
02da662c083396641da96c1d32fc86ed?d=identicon&s=25 KOSAKI Motohiro (Guest)
on 2012-08-30 00:45
(Received via mailing list)
>>> +1
>>
>> $B$o$?$7$b(B +1$B!#(B
>
> $B$3!<$f$&$N$,(B++$B$G$J$$$N$,(BRubyist$B$+!"$C$F;W$$$^$7$?!#(B
> $B!J$R$g$C$H$7$F(BRuby$B3&$G$O>o<1!)(B +=1$B$8$c$J$$$s$G$9$M!#!K(B

$B$?$V$s$=$&$$$&8@8lH~0U<1E*$J?<$$0UL#$O$J$/$F$?$s$K(Bruby-core$B$G(B +1
$B$r;H$&?M$,(B
$BB?$$$N$G$=$l$K1F6A$5$l$F$k$@$1$@$H;W$$$^$9$h(B
308cbef6e86dfc49cce3b2d4cf42aedc?d=identicon&s=25 SASADA Koichi (Guest)
on 2012-09-04 15:06
(Received via mailing list)
(2012/08/27 22:35), NARUSE, Yui wrote:
> (2012/08/27 17:46), KOSAKI Motohiro wrote:
>>>> $B8e<T$N6qBNE*<jK!$O$$$/$D$+$"$k$H;W$$$^$9$,!"B(CM$O:G=i$+$i(B frozen
$B$K$7$F$*$/$H$+$b$"$j$+$J$H;W$C$F$$$^$9!#(B
>>>
>>> $B!!(BNumeric $B$O(B freeze $B$7$A$c$&!$$H$$$&$N$@$H$d$j2a$.$G$7$g$&$+!%(B
>>
>>
$B$\$/$O$"$j$@$H$*$b$&!#?t$H$$$&35G0$O@$3&$,$O$8$^$k$h$jA0$+$i$"$C$?$N$@!"%`%O%O%O%O%O$H$$$&@$3&$G$9$J(B
>
> $B$=$&$G$9$M!"$=$&$9$k$HE}0l46$,=P$k$s$8$c$J$$$+$J$!$H;W$C$F$$$^$9!#(B

$B!!$H$j$"$($:1F6A$,>/$J$=$&$J!$(BFloat $B$@$1(B frozen
$B$K$7$A$c$&$N$O$I$&$G$7$g(B
$B$&$+!%(B
9361878d459f1709feec780518946ee5?d=identicon&s=25 naruse (Yui NARUSE) (Guest)
on 2012-09-05 04:10
(Received via mailing list)
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
https://bugs.ruby-lang.org/issues/6936#change-29181

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


[Feature #6763] などで議論されていた flonum が r36798 でが入ったわけですが、

1. Float のオブジェクトID の仕様が変更
2. flonum な float に特異メソッドが追加不可
3. flonum な float に特異クラスが作成不可
4. 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 っぽいオブジェクトにも当てはまる気がしています。
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 matz (Yukihiro Matsumoto) (Guest)
on 2012-10-27 01:39
(Received via mailing list)
Issue #6936 has been updated by matz (Yukihiro Matsumoto).

Assignee changed from matz (Yukihiro Matsumoto) to ko1 (Koichi Sasada)

OK, I'd like to see if everything goes well.  Merge it.

Matz.

----------------------------------------
Feature #6936: Forbid singleton class and instance variabls for float
https://bugs.ruby-lang.org/issues/6936#change-31722

Author: naruse (Yui NARUSE)
Status: Assigned
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0


[Feature #6763] などで議論されていた flonum が r36798 でが入ったわけですが、

1. Float のオブジェクトID の仕様が変更
2. flonum な float に特異メソッドが追加不可
3. flonum な float に特異クラスが作成不可
4. 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 っぽいオブジェクトにも当てはまる気がしています。
308cbef6e86dfc49cce3b2d4cf42aedc?d=identicon&s=25 SASADA Koichi (Guest)
on 2012-10-27 02:06
(Received via mailing list)
(2012/10/27 8:38), matz (Yukihiro Matsumoto) wrote:
> Assignee changed from matz (Yukihiro Matsumoto) to ko1 (Koichi Sasada)
>
> OK, I'd like to see if everything goes well.  Merge it.

Roger, boss.
308cbef6e86dfc49cce3b2d4cf42aedc?d=identicon&s=25 SASADA Koichi (Guest)
on 2012-10-27 03:02
(Received via mailing list)
(2012/10/27 9:05), SASADA Koichi wrote:
> (2012/10/27 8:38), matz (Yukihiro Matsumoto) wrote:
>> Assignee changed from matz (Yukihiro Matsumoto) to ko1 (Koichi Sasada)
>>
>> OK, I'd like to see if everything goes well.  Merge it.

とりあえずの速報ですが,
test-all では下記のエラー:

> [ 2709/11367] TestClass#test_singleton_class = 0.00 s
> Message: <"can't modify frozen Float">
>     /mnt/sdb1/ruby/trunk/test/ruby/marshaltestlib.rb:224:in `test_float_extend'
>   6) Error:
> test_float_ivar_self(TestMarshal):
> RuntimeError: can't modify frozen Float
>     /mnt/sdb1/ruby/trunk/test/ruby/marshaltestlib.rb:218:in `block in
test_float_ivar_self'
>     /mnt/sdb1/ruby/trunk/test/ruby/marshaltestlib.rb:218:in `instance_eval'
>     /mnt/sdb1/ruby/trunk/test/ruby/marshaltestlib.rb:218:in
`test_float_ivar_self'
>
> Finished tests in 563.933874s, 20.1566 tests/s, 6086.8360 assertions/s.
> 11367 tests, 3432573 assertions, 2 failures, 4 errors, 29 skips

test-ruby spec のほうでは

1)
String#% taints result for %s when argument is tainted ERROR
RuntimeError: can't modify frozen Float
/mnt/sdb1/ruby/trunk/spec/ruby spec/core/string/modulo_spec.rb:654:in
`taint'
/mnt/sdb1/ruby/trunk/spec/ruby spec/core/string/modulo_spec.rb:654:in
`block (2 levels) in <top (required)>'
/mnt/sdb1/ruby/trunk/spec/ruby spec/core/string/modulo_spec.rb:4:in
`<top (required)>'

というエラーが出ました.

とりあえず,テストを直せば良さそうだなぁと思っています.
308cbef6e86dfc49cce3b2d4cf42aedc?d=identicon&s=25 SASADA Koichi (Guest)
on 2012-10-27 03:46
(Received via mailing list)
(2012/10/27 10:02), SASADA Koichi wrote:
> とりあえず,テストを直せば良さそうだなぁと思っています.

直しながら考えてたんですが,現在

- 1 や :sym などは "can't define singleton method (TypeError)"
- frozen object は "can't modify frozen Float (RuntimeError)" のよう
に,RuntimeError

になります.

なるせさんのパッチでは,「Float の場合は TypeError」としようとしているん
ですが,これを frozen だったら TypeError にするべきか,どうか迷っており
ます.

frozen は type じゃないから,従来通り RuntimeError で良いですかね?
Fixnum など,および frozen object なら TypeError というのもアリかとふと
思ったのでした.


(Float で分岐を分けると,Bignum も frozen にしようって議論が出てきたと
き,じゃあここをどうする,とまた悩みそうだと思った次第です)

 とりあえず,なるせさんのパッチにちょっと足して,テスト修正して通ること
を確認しました.


>  #define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)
> +    else {
> @@ -620,6 +620,7 @@ rb_float_new_in_heap(double d)
> +++ vm.c  (working copy)
> ===================================================================
> -  end
> -    marshal_equal(o1) { |o|
>      marshal_equal(1..2)
> -    else
> +++ test/test_pp.rb  (working copy)
>    def test_to_s_without_iv
 rubyspec のほうはまだ見ておりません.コメント頂ければ幸いです.
308cbef6e86dfc49cce3b2d4cf42aedc?d=identicon&s=25 SASADA Koichi (Guest)
on 2012-10-27 04:09
(Received via mailing list)
(2012/09/05 11:09), naruse (Yui NARUSE) wrote:
> 以下のような感じですかね

このパッチで気づいたんですが(これをあてると),

p 1.frozen?   #=> false
p 1.0.frozen? #=> true

のように,Float は frozen なんですが,Fixnum は frozen じゃないんですね.
308cbef6e86dfc49cce3b2d4cf42aedc?d=identicon&s=25 SASADA Koichi (Guest)
on 2012-10-27 04:19
(Received via mailing list)
(2012/10/27 10:45), SASADA Koichi wrote:
>  rubyspec のほうはまだ見ておりません.コメント頂ければ幸いです.

    ("%s" % -0.0.taint).tainted?.should == true # -0.0 is not flonum

こういうテストなんですが,消せば良いんではないかと思います.

# -0.0 は flonum じゃない,ってのは ad-hoc 過ぎる気がしますが....
9361878d459f1709feec780518946ee5?d=identicon&s=25 naruse (Yui NARUSE) (Guest)
on 2012-10-29 03:26
(Received via mailing list)
Issue #6936 has been updated by naruse (Yui NARUSE).


ko1 (Koichi Sasada) wrote:
> (2012/10/27 10:45), SASADA Koichi wrote:
>  >  rubyspec のほうはまだ見ておりません.コメント頂ければ幸いです.
>
>      ("%s" % -0.0.taint).tainted?.should == true # -0.0 is not flonum
>
>  こういうテストなんですが,消せば良いんではないかと思います.
>
>  # -0.0 は flonum じゃない,ってのは ad-hoc 過ぎる気がしますが....

それも含めて現状に合わせておきました。
----------------------------------------
Feature #6936: Forbid singleton class and instance variabls for float
https://bugs.ruby-lang.org/issues/6936#change-31906

Author: naruse (Yui NARUSE)
Status: Closed
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0


[Feature #6763] などで議論されていた flonum が r36798 でが入ったわけですが、

1. Float のオブジェクトID の仕様が変更
2. flonum な float に特異メソッドが追加不可
3. flonum な float に特異クラスが作成不可
4. 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 っぽいオブジェクトにも当てはまる気がしています。
This topic is locked and can not be replied to.