【问题标题】:Ruby - defining self method in metaclass of a ruby classRuby - 在 ruby​​ 类的元类中定义 self 方法
【发布时间】: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
  • 这有点像问“我写了这段代码,但我不知道它是做什么的,是吗?” :-) 你想要完成什么?跨度>

标签: ruby metaprogramming metaclass class-method


【解决方案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

【讨论】:

  • 这个问题与元编程无关
猜你喜欢
  • 1970-01-01
  • 2015-03-03
  • 1970-01-01
  • 2016-06-30
  • 2011-05-19
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多