ささだです.

Yusuke ENDOH wrote::
> ObjectSpace を使うと種々のリテラルを書き換えることができてしまうようですが、
> 仕様でしょうか。

 他にも,Regexp などの Immutable と言われてるオブジェクトに勝手に特異メ
ソッドなりを追加できちゃう,とかもあります.Regexp なんかは,リテラルで
毎回同じオブジェクトを返すので,仕様的にはどう解決したものだか(これはそ
のままとするのが仕様かもしれない).影響としてぱっと思いつくのは,恐くな
いんですが Marshal をさせないようにするような嫌がらせです.

def xyzzy
  p Marshal.dump(/xyzzy/)
end

ObjectSpace.each_object(Regexp){|e|
  if /xyzzy/ =~ e.to_s
    unless e.frozen?
      begin
        def e.foo
        end
      rescue TypeError
        p e
      end
      e.instance_eval{
        @a = 1
      }
    end
  end
}

xyzzy #=> singleton can't be dumped (TypeError)


 なお,いただいたパッチについては,以下のようなほうが確実かなぁ,なんて
思いました.


Index: compile.c
===================================================================
--- compile.c	(リビジョン 22118)
+++ compile.c	(作業コピー)
@@ -398,6 +398,13 @@
 iseq_add_mark_object(rb_iseq_t *iseq, VALUE v)
 {
     if (!SPECIAL_CONST_P(v)) {
+	switch (BUILTIN_TYPE(v)) {
+	  case T_STRING:
+	  case T_ARRAY:
+	    dp(v);
+	    rb_obj_freeze(v);
+	}
+
 	rb_ary_push(iseq->mark_ary, v);
     }
     return COMPILE_OK;

-- 
// SASADA Koichi at atdot dot net