CLASS_VERVS实例_VERA [英] class_eval vs instance_eval
本文介绍了CLASS_VERVS实例_VERA的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
def
之外,class_eval
&;instance_eval
的工作方式有什么不同?class_eval
块def
将方法定义为类本身(即实例方法),而instance_eval
块def
将方法定义为类的特征类(即类方法)。AFAIK所有其他功能在这两种情况下的工作方式相同(例如,定义常量的define_method
、attr_accessor
、class << self; end
)。这是真的吗?
答案是:def
、undef
和alias
对于class_eval
和instance_eval
具有不同的上下文。
推荐答案
长话短说:
Object.instance_eval &block
套:self
至Object
- 将当前类设置为
Object.singleton_class
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
或Class
实例作为klass
和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
。最后:
从
/li>module_eval
调用时,under
将为Class
或Module
实例。从
instance_eval
调用时,under
将是的单例类self
。
这篇关于CLASS_VERVS实例_VERA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文