访问 Ruby 中的元类

Getting access to the metaclass in Ruby

我正在尝试更好地理解 Ruby 的规则以及如何访问元类。我正在阅读 Yehuda Katz 关于元编程的文章,我发现了这个:

matz = Object.new  
def matz.speak  
  "Place your burden to machine's shoulders"
end

matz.class #=> Object  

其实matz的"class"就是它的不可见元类。我们甚至可以访问元类:

metaclass = class << matz; self; end  
metaclass.instance_methods.grep(/speak/) #=> ["speak"]

这一行发生了什么:

metaclass = class << matz; self; end  

是否与以下内容相同:

matz
   self
end

?

class << matz; self; end 等同于

class << mats
  self
end

class << matz; end打开单例class(Ruby元class的正式名称)。它也是一个表达式,其中 return 是在其中计算的最后一个表达式的 return 值,在本例中为 self.

我认为您对 self 很熟悉,因为您正在玩元编程。当 self 在 class 的范围内时,它指的是 class 本身,在您的代码中,它指的是单例 class.

P.S。从Ruby 1.9.2开始,就不用再用这种铲子语法来抓单例了[=2​​6=]。就 obj.singleton_class.

What is going on on this line:

metaclass = class << matz; self; end  
class << foo

打开 foo 的单例 class。在 class 定义体中,self 是 class。 class 定义体的 return 值是 class 定义体中最后一个表达式的值。

所以,我们给class定义体赋值,也就是class定义体里面最后一个表达式的值,也就是self,也就是class,即 matz 的单例 class。

也就是说:我们把matz的单例class赋值给局部变量metaclass.

请注意,现代 Ruby 具有用于该目的的 Object#singleton_class 方法(添加于 Ruby 1.9.2,于 2010 年发布)。

Is that the same as:

matz
   self
end

显然不是,因为前者是合法语法,而这不是。