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

ruby-changes:38291

From: nobu <ko1@a...>
Date: Thu, 23 Apr 2015 11:36:13 +0900 (JST)
Subject: [ruby-changes:38291] nobu:r50372 (trunk): vm_eval.c: allow symbols to instance_eval/exec

nobu	2015-04-23 11:35:58 +0900 (Thu, 23 Apr 2015)

  New Revision: 50372

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

  Log:
    vm_eval.c: allow symbols to instance_eval/exec
    
    * vm_eval.c (rb_obj_instance_eval, rb_obj_instance_exec): allow
      symbols to just instance_eval/exec, execept for definition of
      singletons.  [ruby-core:68961] [Bug #11086]

  Modified files:
    trunk/ChangeLog
    trunk/class.c
    trunk/test/ruby/test_symbol.rb
    trunk/vm_eval.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 50371)
+++ ChangeLog	(revision 50372)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Apr 23 11:35:55 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* vm_eval.c (rb_obj_instance_eval, rb_obj_instance_exec): allow
+	  symbols to just instance_eval/exec, execept for definition of
+	  singletons.  [ruby-core:68961] [Bug #11086]
+
 Thu Apr 23 10:01:36 2015  SHIBATA Hiroshi  <hsbt@r...>
 
 	* lib/delegate.rb: fix a typo.
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 50371)
+++ vm_eval.c	(revision 50372)
@@ -1627,6 +1627,20 @@ specific_eval(int argc, const VALUE *arg https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1627
     }
 }
 
+static VALUE
+singleton_class_for_eval(VALUE self)
+{
+    if (SPECIAL_CONST_P(self)) {
+	return rb_special_singleton_class(self);
+    }
+    switch (BUILTIN_TYPE(self)) {
+      case T_FLOAT: case T_BIGNUM: case T_SYMBOL:
+	return Qnil;
+      default:
+	return rb_singleton_class(self);
+    }
+}
+
 /*
  *  call-seq:
  *     obj.instance_eval(string [, filename [, lineno]] )   -> obj
@@ -1663,14 +1677,7 @@ specific_eval(int argc, const VALUE *arg https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1677
 VALUE
 rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self)
 {
-    VALUE klass;
-
-    if (SPECIAL_CONST_P(self)) {
-	klass = rb_special_singleton_class(self);
-    }
-    else {
-	klass = rb_singleton_class(self);
-    }
+    VALUE klass = singleton_class_for_eval(self);
     return specific_eval(argc, argv, klass, self);
 }
 
@@ -1695,14 +1702,7 @@ rb_obj_instance_eval(int argc, const VAL https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1702
 VALUE
 rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self)
 {
-    VALUE klass;
-
-    if (SPECIAL_CONST_P(self)) {
-	klass = rb_special_singleton_class(self);
-    }
-    else {
-	klass = rb_singleton_class(self);
-    }
+    VALUE klass = singleton_class_for_eval(self);
     return yield_under(klass, self, rb_ary_new4(argc, argv));
 }
 
Index: class.c
===================================================================
--- class.c	(revision 50371)
+++ class.c	(revision 50372)
@@ -1539,7 +1539,8 @@ singleton_class_of(VALUE obj) https://github.com/ruby/ruby/blob/trunk/class.c#L1539
 {
     VALUE klass;
 
-    if (FIXNUM_P(obj) || FLONUM_P(obj) || SYMBOL_P(obj)) {
+    if (FIXNUM_P(obj) || FLONUM_P(obj) || STATIC_SYM_P(obj)) {
+      no_singleton:
 	rb_raise(rb_eTypeError, "can't define singleton");
     }
     if (SPECIAL_CONST_P(obj)) {
@@ -1549,9 +1550,9 @@ singleton_class_of(VALUE obj) https://github.com/ruby/ruby/blob/trunk/class.c#L1550
 	return klass;
     }
     else {
-	enum ruby_value_type type = BUILTIN_TYPE(obj);
-	if (type == T_FLOAT || type == T_BIGNUM) {
-	    rb_raise(rb_eTypeError, "can't define singleton");
+	switch (BUILTIN_TYPE(obj)) {
+	  case T_FLOAT: case T_BIGNUM: case T_SYMBOL:
+	    goto no_singleton;
 	}
     }
 
Index: test/ruby/test_symbol.rb
===================================================================
--- test/ruby/test_symbol.rb	(revision 50371)
+++ test/ruby/test_symbol.rb	(revision 50372)
@@ -199,6 +199,35 @@ class TestSymbol < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_symbol.rb#L199
     assert_raise(TypeError) { a = :foo; def a.foo; end }
   end
 
+  SymbolsForEval = [
+    :foo,
+    "dynsym_#{Random.rand(10000)}_#{Time.now}".to_sym
+  ]
+
+  def test_instance_eval
+    bug11086 = '[ruby-core:68961] [Bug #11086]'
+    SymbolsForEval.each do |sym|
+      assert_nothing_raised(TypeError, sym, bug11086) {
+        sym.instance_eval {}
+      }
+      assert_raise(TypeError, sym, bug11086) {
+        sym.instance_eval {def foo; end}
+      }
+    end
+  end
+
+  def test_instance_exec
+    bug11086 = '[ruby-core:68961] [Bug #11086]'
+    SymbolsForEval.each do |sym|
+      assert_nothing_raised(TypeError, sym, bug11086) {
+        sym.instance_exec {}
+      }
+      assert_raise(TypeError, sym, bug11086) {
+        sym.instance_exec {def foo; end}
+      }
+    end
+  end
+
   def test_frozen_symbol
     assert_equal(true, :foo.frozen?)
     assert_equal(true, :each.frozen?)

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

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