0

我最近发现了一篇关于 Ruby 中的隐式上下文的有趣文章,我发现这段经历非常开放。我知道 Ruby 不仅包含对self默认方法接收器)的引用,还包含对当前类(也称为默认定义`klass')的引用。

从文章中,假设class定义将当前类self当前类都设置为正在定义的类应该是正确的;就我们考虑普通的方法定义(即不使用点语法来定义单例方法)而言,在方法定义的上下文中,用def,self指的是接收对象,并且当前类没有改变。

我认为不考虑点语法来定义是安全的原因是 Ruby 还提供了一种打开类的特征类的显式方法,而我感兴趣的是了解在打开特征类时如何管理这两个隐式上下文.

使用def 众所周知的语法打开一个特征类:

class << A
  p self

  def foo
    # ...
  end
end

将 foo 定义为 的单例方法A即其 eigenclass 的实例方法(be it A')。这段代码也会打印#<Class:A>,所以说<<语法将当前类self当前类都设置为正确A'吗?

4

2 回答 2

1

是的,它实际上在 A' 的控制下打开了块。您也可以说它的工作原理类似于 A' 的 class_eval。

于 2012-11-04T13:18:17.017 回答
1

其实你写的和写的完全一样:

class A
  class << self
    def foo
      #...
    end
  end
end

class << self 语法表示后面会出现一个定义块,这将直接转到传递给 << 的对象的特征类。是的,我说的是对象,而不是类。试试这个(提供上面的类定义):

a = A.new
class << a
  def foo2
  end
end
a.singleton_methods
b = A.new
b.singleton_methods

这意味着,在这种情况下,您在对象 a 的 eigenclass 中定义方法 foo2。但这是对象本身的特征类,而不是类。因此,同一类的其他对象将不会共享此 foo2 定义。

那么这意味着什么?Ruby 是(或声称是)一种纯 OO 语言。一切都是对象。您定义的类的对象是对象。您定义的类也是一个对象。类的类型。它继承自 Object. 在 Ruby 中,所有对象都有一个 eigenclass。实际上,“类方法”的定义只是对其概念的一种解释。“类方法”并不是真正的类方法,而是在类的 eigenclass 中定义的方法。因此,当您调用“类方法”时,您确实是在调用对象方法。这个对象恰好是你定义的一个类。你如何定义特征类方法?正是 class << self 语法。在这种情况下,“自我”是您作为参数传递给类 << 的任何内容。

于 2012-11-04T13:41:10.453 回答