[前][次][番号順一覧][スレッド一覧]

ruby-changes:24596

From: nobu <ko1@a...>
Date: Tue, 7 Aug 2012 00:32:04 +0900 (JST)
Subject: [ruby-changes:24596] nobu:r36647 (trunk): method in instance_eval

nobu	2012-08-07 00:31:13 +0900 (Tue, 07 Aug 2012)

  New Revision: 36647

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=36647

  Log:
    method in instance_eval
    
    * class.c (rb_special_singleton_class_of): utility function.
    * vm_eval.c (eval_under): special deal for class variable scope with
      instance_eval.
    * vm_eval.c (rb_obj_instance_eval, rb_obj_instance_exec): allow method
      definition in instance_eval of special constants.  [ruby-core:28324]
      [Bug #2788]

  Modified files:
    trunk/ChangeLog
    trunk/bootstraptest/test_eval.rb
    trunk/class.c
    trunk/internal.h
    trunk/test/ruby/test_eval.rb
    trunk/vm_eval.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 36646)
+++ ChangeLog	(revision 36647)
@@ -1,3 +1,14 @@
+Tue Aug  7 00:31:09 2012  Nobuyoshi Nakada  <nobu@r...>
+
+	* class.c (rb_special_singleton_class_of): utility function.
+
+	* vm_eval.c (eval_under): special deal for class variable scope with
+	  instance_eval.
+
+	* vm_eval.c (rb_obj_instance_eval, rb_obj_instance_exec): allow method
+	  definition in instance_eval of special constants.  [ruby-core:28324]
+	  [Bug #2788]
+
 Tue Aug  7 00:23:58 2012  Nobuyoshi Nakada  <nobu@r...>
 
 	* variable.c (CVAR_LOOKUP): split into helper functions.
Index: bootstraptest/test_eval.rb
===================================================================
--- bootstraptest/test_eval.rb	(revision 36646)
+++ bootstraptest/test_eval.rb	(revision 36647)
@@ -264,24 +264,18 @@
 }, '[ruby-core:16794]'
 
 assert_equal 'ok', %q{
-  begin
-    nil.instance_eval {
-      def a() :a end
-    }
-  rescue TypeError
-    :ok
-  end
-}, '[ruby-core:16796]'
+  nil.instance_eval {
+    def defd_using_instance_eval() :ok end
+  }
+  nil.defd_using_instance_eval
+}, '[ruby-core:28324]'
 
 assert_equal 'ok', %q{
-  begin
-    nil.instance_exec {
-      def a() :a end
-    }
-  rescue TypeError
-    :ok
-  end
-}, '[ruby-core:16796]'
+  nil.instance_exec {
+    def defd_using_instance_exec() :ok end
+  }
+  nil.defd_using_instance_exec
+}, '[ruby-core:28324]'
 
 assert_normal_exit %q{
   eval("", method(:proc).call {}.binding)
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 36646)
+++ vm_eval.c	(revision 36647)
@@ -1320,6 +1320,9 @@
 {
     NODE *cref = vm_cref_push(GET_THREAD(), under, NOEX_PUBLIC, NULL);
 
+    if (FL_TEST(under, FL_SINGLETON) || (SPECIAL_CONST_P(self) && !NIL_P(under))) {
+	cref->flags |= NODE_FL_CREF_PUSHED_BY_EVAL;
+    }
     if (rb_safe_level() >= 4) {
 	StringValue(src);
     }
@@ -1387,7 +1390,7 @@
     VALUE klass;
 
     if (SPECIAL_CONST_P(self)) {
-	klass = Qnil;
+	klass = rb_special_singleton_class(self);
     }
     else {
 	klass = rb_singleton_class(self);
@@ -1419,7 +1422,7 @@
     VALUE klass;
 
     if (SPECIAL_CONST_P(self)) {
-	klass = Qnil;
+	klass = rb_special_singleton_class(self);
     }
     else {
 	klass = rb_singleton_class(self);
Index: class.c
===================================================================
--- class.c	(revision 36646)
+++ class.c	(revision 36647)
@@ -1286,7 +1286,21 @@
     }\
 } while (0)
 
+static inline VALUE
+special_singleton_class_of(VALUE obj)
+{
+    SPECIAL_SINGLETON(Qnil, rb_cNilClass);
+    SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
+    SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
+    return Qnil;
+}
 
+VALUE
+rb_special_singleton_class(VALUE obj)
+{
+    return special_singleton_class_of(obj);
+}
+
 /*!
  * \internal
  * Returns the singleton class of \a obj. Creates it if necessary.
@@ -1304,11 +1318,11 @@
     if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
 	rb_raise(rb_eTypeError, "can't define singleton");
     }
-    if (rb_special_const_p(obj)) {
-	SPECIAL_SINGLETON(Qnil, rb_cNilClass);
-	SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
-	SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
-	rb_bug("unknown immediate %p", (void *)obj);
+    if (SPECIAL_CONST_P(obj)) {
+	klass = special_singleton_class_of(obj);
+	if (NIL_P(klass))
+	    rb_bug("unknown immediate %p", (void *)obj);
+	return klass;
     }
 
     if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
Index: internal.h
===================================================================
--- internal.h	(revision 36646)
+++ internal.h	(revision 36647)
@@ -60,6 +60,7 @@
 VALUE rb_obj_private_methods(int argc, VALUE *argv, VALUE obj);
 VALUE rb_obj_public_methods(int argc, VALUE *argv, VALUE obj);
 int rb_obj_basic_to_s_p(VALUE);
+VALUE rb_special_singleton_class(VALUE);
 void Init_class_hierarchy(void);
 
 /* compile.c */
Index: test/ruby/test_eval.rb
===================================================================
--- test/ruby/test_eval.rb	(revision 36646)
+++ test/ruby/test_eval.rb	(revision 36647)
@@ -200,6 +200,21 @@
     end
   end
 
+  def test_instance_eval_method
+    bug2788 = '[ruby-core:28324]'
+    [Object.new, [], nil, true, false].each do |o|
+      assert_nothing_raised(TypeError, "#{bug2788} (#{o.inspect})") do
+        o.instance_eval {
+          def defd_using_instance_eval() :ok end
+        }
+      end
+      assert_equal(:ok, o.defd_using_instance_eval)
+      class << o
+        remove_method :defd_using_instance_eval
+      end
+    end
+  end
+
   #
   # From ruby/test/ruby/test_eval.rb
   #

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]