Ruby - 在 ruby​​ 类的元类中定义 self 方法

Posted

技术标签:

【中文标题】Ruby - 在 ruby​​ 类的元类中定义 self 方法【英文标题】:Ruby - defining self method in metaclass of a ruby class 【发布时间】:2018-06-28 16:55:36 【问题描述】:
class A
  @@class_var = "A class variable"
  def initialize
    @var = "A instance variable"
  end
  def m1
    puts @var
  end
  def m2
    puts @@class_var
  end
end

class << A
  def self.m3
    puts "im m3"
  end
end

方法 m3 发生了什么以及如何访问 m3 方法以及它将在类或元类中的何处定义?但是,如果我尝试使用 A.m3 或 Object 类方法访问它,它就不存在了!!

【问题讨论】:

简短的回答是删除self 这有点像问“我写了这段代码,但我不知道它是做什么的,是吗?” :-) 你想要完成什么?跨度> 【参考方案1】:

Ruby 中的每个对象都有一个隐藏的单例类,位于其自身与其父类之间。

class A; end
a = A.new
a.is_a? a.singleton_class                  # true
a.singleton_class.superclass == A          # true
# similarly
A.is_a? A.singleton_class                  # true
A.singleton_class.ancestors.include? Class # true 

单例类很有用,因为它允许您定义仅适用于单个对象的方法。

您可以打开一个对象的单例类以使用class &lt;&lt; 符号对其进行更改。

class << a
  def foobar
  end
end
a.foobar

但是在单例类中定义方法也有一个简写:

def a.foobar
  # same effect as above
end
a.foobar

您结合了这两种表示法,因此最终在 A 的单例类的单例类中定义了一个方法。当你在a的单例类中定义一个方法时,你可以在a上调用它,这样你的方法就可以在A的单例类上调用。

class << A
  # you opened the singleton class, so self is A.singleton_class
  def self.m3
    puts "im m3"
  end
end
A.singleton_class.m3
# in m3

【讨论】:

这个问题与元编程无关

以上是关于Ruby - 在 ruby​​ 类的元类中定义 self 方法的主要内容,如果未能解决你的问题,请参考以下文章

Ruby 与 Python 元类的类比是啥?

如何在我的元类中获取类的父类?

Ruby 元类混淆

从它的元类python引用一个类的实例

python中的元类作用?

使用装饰器设置类的元类