【问题标题】:class method `self.` within class methods block `class << self` in Ruby类方法中的类方法`self.`在Ruby中阻止`class << self`
【发布时间】:2019-08-20 09:03:09
【问题描述】:

上下文:我目前正在使用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 模式,还是我不应该做的事情,也不在乎?

【问题讨论】:

  • Foo.singleton_class.met 显然。您打开一个单例类并在其单例类上定义一个方法。
  • 我想要一些关于否决票的解释......和@AlekseiMatiushkin 我一直在寻找singleton_class 的解释,但每个案例都引用singleton_class 的用法而不是类的实例.因此我真的不明白这里的用法:/
  • 投反对票不是我的;我会发布答案来解释细节。
  • 为了人类的恒常性而投票。

标签: ruby ruby-2.5


【解决方案1】:

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

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

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

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

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

这不是很实用,但由于 Ruby 将所有内容都视为Object,它仍然是可能的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 2015-03-03
    • 2018-06-28
    • 2011-05-19
    • 2019-12-06
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多