类方法中的类方法`self.`在Ruby

时间:2019-08-20 09:03:09

标签: ruby ruby-2.5

上下文:我目前正在使用parser gem,并试图处理什么是公共方法的所有情况。

我已经编写了下一个代码,希望它在运行时失败。但事实并非如此。

class Foo
  class << self
    def self.met
      puts "I'm just a troll"
    end

    class << self
      def mut
        puts "Try and find me"
      end
    end
  end
end

所以我想知道met在哪里可调用(Foo.met会引发NoMethodError)吗?这是有用的Ruby模式还是只是我不应该做的事,也不在乎?

1 个答案:

答案 0 :(得分:5)

Ruby中的每个对象都有自己的singleton class。在这里定义了所有实例方法。

请考虑以下示例。

class C; end
c1, c2 = C.new, C.new
c1.extend(Module.new { def m1; 42; end })

c1.m1
#⇒ 42
c2.m1
#⇒ NoMethodError: undefined method `m1' for #<C:0x000055cb062e6888>

c1.singleton_class.instance_methods.grep /m1/
#⇒ [:m1]
c2.singleton_class.instance_methods.grep /m1/
#⇒ []

需要Singleton类来扩展对象等。

在Ruby中,一切都是对象。类确实也是对象。这就是每个班级都有自己的单例班级的原因。每个单例类都有其单例类。

c1.singleton_class.singleton_class.singleton_class.singleton_class
#⇒ #<Class:#<Class:#<Class:#<Class:#<C:0x000055cb0459c700>>>>>

foo上定义的方法存储foo的单例类中。在foo的单例类中定义的方法存储foo的单例类的singleton类中。依此类推。

虽然不太实用,但由于Ruby如何将所有内容都视为Object,因此仍然有可能。