gpt4 book ai didi

ruby - class_eval 与 instance_eval

转载 作者:数据小太阳 更新时间:2023-10-29 06:57:36 26 4
gpt4 key购买 nike

class_eval 有什么区别吗? & instance_eval工作除了def ?里面class_eval block def定义类自身的方法(即实例方法)和内部 instance_eval def为类的特征类定义方法(即类方法)。据我所知,所有其他功能在这两种情况下的工作方式相同(例如 define_methodattr_accessorclass << self; end ,定义常量)。是真的吗?

答案是:def , undefalias class_eval 有不同的上下文和 instance_eval .

最佳答案

长话短说:

  • Object.instance_eval &block套:
  • Object.class_eval &block套:
    • selfObject
    • “当前类(class)”到Object

“当前类”用于 def , undefalias ,以及常量和类变量查找。


现在,让我们看一下实现细节。

这是如何 module_eval instance_eval 在 C 中实现:

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 klassVALUE self .

注意:

  • module_eval通过 ModuleClass实例为 klass self
  • instance_eval将对象的单例类 作为klass 传递

如果给定一个 block ,specific_eval会调用 yield_under ,它采用以下参数:VALUE under , VALUE selfVALUE values .

if (rb_block_given_p()) {
rb_check_arity(argc, 0, 0);
return yield_under(klass, self, Qundef);
}

yield_under中有两行很重要:

  1. block.self = self;

    这设置了 self block 的接收者。

  2. cref = vm_cref_push(th, under, NOEX_PUBLIC, blockptr);

    cref 是一个链表它指定了“当前类”,用于 def , undefalias , 还有作为常量和类变量查找。

    该行基本上设置了 crefunder .

    最后:

    • module_eval 调用时, under将是 ClassModule实例。

    • instance_eval 调用时, under将是 单例类 self .

关于ruby - class_eval 与 instance_eval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10302138/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com