2

上下文:我目前正在使用解析器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会引发 a NoMethodError)?这是一个有用的 Ruby 模式,还是我不应该做的事情,也不在乎?

4

1 回答 1

5

Ruby 中的每个对象都有自己的单例类。这是定义所有实例方法的地方。

考虑以下示例。

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/
#⇒ []

需要单例类才能扩展对象等。

在 Ruby 中,一切都是对象。类确实也是对象。这就是为什么每个类都有自己的单例类。每个单例类都有其单例类。

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

上定义的foo方法存储foo. foo在的单例类上定义的方法存储在 的单例类的单例类中foo。等等。

这不太实用,但由于 Ruby 将所有内容都视为Object.

于 2019-08-20T09:51:58.950 回答