元编程:当我们调用类方法内部定义的实例方法时,方法调度在哪里



我正在阅读元编程Ruby,只想澄清以下转述的代码:

class MyClazz
  def self.my_class_method(name)
    define_method(name) {
      # do stuff
    }
  end
  my_class_method :foo
  my_class_method :bar
end
# The code above generates instance methods:
# def foo
#   do stuff
# end
# def bar
#   do stuff
# end

Q1我的第一个问题涉及文件末尾的两个方法调用:my_class_method :foomy_class_method :bar。当MyClazz对象被实例化时,它们都会被自动调用,我的想法是对的吗?

Q2当Ruby生成这些方法(def foodef bar)时,它会将它们放在MyClazz的本征类中,即使它们是实例方法。那么,这是否意味着Ruby在需要时同时考虑类和实例方法的本征类?

我只是想在深入到书中之前澄清一下。

答案1: (短)当ruby实例化MyClass实例(类型为Class)时调用它们。

(long)当Ruby解释器看到一个类定义(class MyClazz)时,它会实例化这个类的一个实例,并评估类定义中的所有代码。

在您的例子中,MyClazz是一个常量,它保持对类Class的对象的引用。当Ruby初始化它时,它在类定义中执行代码——定义这个Class实例的singleton方法my_class_method,并在这个Class实例的上下文中执行两次方法my_class_method

答案2: (短)Module#define_method私有方法将方法添加到Class实例的方法表中(方法表保存类的实例方法)。它不影响距离对象/类对象的本征类。

(long)当您在对象上调用实例方法时,Ruby首先在该对象的本征类中查找该方法,然后在本征类的超类中查找(它将是该对象类的Class对象)。但它不会出现在MyClazz的本征类中对象

示例:

obj = MyClazz.new
obj.foo # => ok

obj.foo将在obj对象的本征类中查找foo方法定义,然后查找MyClass的实例方法(类Class的实例),然后在MyClass对象的超类中(在您的情况下,这是Object类)等

obj = MyClass.new
MyClass.my_class_method :baz
obj.baz # => ok

MyClass.my_class_method将在MyClass对象的本征类中寻找my_class_method方法定义称为元类),它将在这里找到它,并将baz实例方法添加到类MyClass中。

A1:是的,这些方法是在实例化时创建的。

A2:Russ Olsen在他的书《Eloquent Ruby》中对此做了很好的解释。本征类(或单例类)"位于每个对象及其正则类之间"。因此,当Ruby在实例方法中找不到它要查找的方法时,它将开始向上遍历继承树。下一站是本征类,然后是类本身。

Olsen还对所有Class方法实际上是新类和Class对象之间的单例方法进行了有趣的讨论。

相关内容

  • 没有找到相关文章

最新更新