1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36647 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2012-08-06 15:31:13 +00:00
parent 353833c466
commit 28827e61d1
6 changed files with 61 additions and 23 deletions

View file

@ -1,3 +1,14 @@
Tue Aug 7 00:31:09 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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@ruby-lang.org>
* variable.c (CVAR_LOOKUP): split into helper functions.

View file

@ -264,24 +264,18 @@ assert_equal 'ok', %q{
}, '[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)

24
class.c
View file

@ -1286,6 +1286,20 @@ rb_undef_method(VALUE klass, const char *name)
}\
} 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
@ -1304,11 +1318,11 @@ singleton_class_of(VALUE obj)
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) &&

View file

@ -60,6 +60,7 @@ VALUE rb_obj_protected_methods(int argc, VALUE *argv, VALUE obj);
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 */

View file

@ -200,6 +200,21 @@ class TestEval < Test::Unit::TestCase
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
#

View file

@ -1320,6 +1320,9 @@ eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
{
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 @@ rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
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 @@ rb_obj_instance_exec(int argc, VALUE *argv, VALUE self)
VALUE klass;
if (SPECIAL_CONST_P(self)) {
klass = Qnil;
klass = rb_special_singleton_class(self);
}
else {
klass = rb_singleton_class(self);