长话短说:
Object.instance_eval &block
套:
Object.class_eval &block
套:
self
至Object
- “当前班级”到
Object
“当前类”用于def
、undef
和alias
以及常量和类变量查找。
现在,让我们看一下实现细节。
以下是在 C 中的实现方式module_eval
和instance_eval
实现方式:
VALUE rb_mod_module_eval(int argc, VALUE *argv, VALUE mod) {
return specific_eval(argc, argv, mod, mod);
}
VALUE rb_obj_instance_eval(int argc, VALUE *argv, VALUE self) {
VALUE klass;
if (SPECIAL_CONST_P(self)) { klass = Qnil; }
else { klass = rb_singleton_class(self); }
return specific_eval(argc, argv, klass, self);
}
两者都调用,specific_eval
它接受以下参数:int argc
、VALUE *argv
和。VALUE klass
VALUE self
注意:
module_eval
将Module
orClass
实例作为两个klass
and传递 self
instance_eval
将对象的单例类传递为klass
如果给定一个块,specific_eval
将调用yield_under
,它接受以下参数VALUE under
:VALUE self
和VALUE values
。
if (rb_block_given_p()) {
rb_check_arity(argc, 0, 0);
return yield_under(klass, self, Qundef);
}
中有两条重要的行yield_under
:
block.self = self;
这将self
块的设置为接收器。
cref = vm_cref_push(th, under, NOEX_PUBLIC, blockptr);
cref
是一个链表,
它指定“当前类”,用于def
、undef
和alias
,以及常量和类变量查找。
该行基本上将 设置cref
为under
。
最后: