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/