こんにちは、なかむら(う)です。

In message "[ruby-dev:37959] [Bug:trunk] I can modify literals"
    on Feb.11,2009 02:16:05, <mame / tsg.ne.jp> wrote:
> バグだとして、リテラルを freeze するパッチを書きましたが、IRC では
> 
>   - freeze で解決するのが正しいやり方なのか
>   - freeze しても finalizer が付け替えできるのではないか
> 
> という感じの指摘がありました。どう直すのがよいでしょう。

元の問題も気になりますが、frozenなオブジェクトに対してfinalizer
を付け替えできてしまうことが気になります。
実際にはObjectSpaceの操作であることや、finalizerからは元のオ
ブジェクトそのものの操作ができるわけではないことなどが理由な
のではないかとは思いますが、付け替えの操作自体はオブジェクト
の内部フラグを変更しているので(あれ、取り除くとき変更してない
な)、禁止してもいいのではないかという気もします。

Index: gc.c =================================================================== --- gc.c (revision 22185) +++ gc.c (working copy) @@ -2261,9 +2261,11 @@ static VALUE undefine_final(VALUE os, VALUE obj) { rb_objspace_t *objspace = &rb_objspace; + if (OBJ_FROZEN(obj)) rb_error_frozen("object"); if (finalizer_table) { st_delete(finalizer_table, (st_data_t*)&obj, 0); } + FL_UNSET(obj, FL_FINALIZE); return obj; } @@ -2283,6 +2285,7 @@ define_final(int argc, VALUE *argv, VALU VALUE obj, block, table; rb_scan_args(argc, argv, "11", &obj, &block); + if (OBJ_FROZEN(obj)) rb_error_frozen("object"); if (argc == 1) { block = rb_block_proc(); }
それでは。 -- U.Nakamura <usa / garbagecollect.jp>