我最近在Ruby中发现了一个隐含上下文的interesting article,我发现这种体验很开心。
我知道Ruby不仅引用了self
(默认方法接收器),还引用了当前类(也称为默认值) definee 或`klass'
)。
从文章中,假设class
定义将self
和当前类设置为正在定义的类,应该是正确的;至于我们考虑普通方法定义(即不使用点语法来定义单例方法),在使用def
的方法定义的上下文中,{{ 1}}指的是接收对象,当前类不会改变。
我觉得安全不考虑点语法定义的原因是Ruby还提供了一种打开类的本征类的明确方法,而我感兴趣的是理解如何打开特征类时会管理这两个隐式上下文。
使用self
使用众所周知的语法打开特征类:
def
将foo定义为class << A
p self
def foo
# ...
end
end
的单例方法,即其本征类的实例方法(be A
)。此代码还会打印A'
,因此,#<Class:A>
语法将<<
和当前类设置为self
是否正确?< / p>
答案 0 :(得分:1)
是的,它实际上是在A'的控制下打开了。 你也可以说它的工作方式类似于A'。
的class_eval答案 1 :(得分:1)
实际上,你所写的内容与写作完全相同:
class A
class << self
def foo
#...
end
end
end
班级&lt;&lt; self语法表示将遵循一个定义块,这将直接转到传递给&lt;&lt;的对象的本征类。是的,我说对象,而不是Class。试试这个(提供上面的类定义):
a = A.new
class << a
def foo2
end
end
a.singleton_methods
b = A.new
b.singleton_methods
这意味着,在这种情况下,您将在对象a的本征类中定义方法foo2。但这是对象本身的本征类,而不是类。因此,同一类的其他对象将不会共享此foo2定义。
那么这意味着什么? Ruby是(或声称是)纯粹的OO语言。一切都是对象。您定义的类的Object是Object。您定义的类也是对象。类型。哪个继承自Object。在Ruby中,所有对象都有一个特征类。实际上,“类方法”的定义只是对其概念的解释。 “类方法”不是真正的类方法,而是在类的本征类中定义的方法。因此,当您调用“类方法”时,您确实在调用对象方法。这个对象恰好是你定义的一个类。你如何定义本征类方法?完全是类&lt;&lt;自我语法。此上下文中的“self”是您作为类&lt;&lt;的参数传递的任何内容。