ruby class << self 块内的常量作用域

ruby constant scope inside a class << self block

给出一个 ruby class 赞

class Thing
  class << self
    NUM = 3

    def speak
      NUM.times { puts "Hi!" }
    end
  end
end

我无法从 class 外部访问 Thing::NUM。如果改为

class Thing
  NUM = 3
  class << self
    def speak
      NUM.times { puts "Hi!" }
    end
  end
end

Thing.speak 仍然按预期工作,但我现在也可以访问 Thing::NUM。我知道 class << self 习语打开了对象的单例 class,但我很困惑为什么这样定义的 class 方法是公开可访问的,但常量不是。

您必须引用正确的 class:

Thing.singleton_class::NUM #=> 3

单例class中常量和方法的引用方式没有不一致:

Thing.methods.include?(:speak)                          #=> true 
Thing.singleton_class.methods.include?(:speak)          #=> false
Thing.singleton_class.instance_methods.include?(:speak) #=> true 

I'm confused why such defined class methods are publicly accessible but constants are not.

是什么让您认为它们不是?

class Thing
  class << self
    NUM = 3
  end
end

Thing.singleton_class::NUM
# => 3

该常量是在 Thing 的单例 class 的范围内定义的,因此您可以在此处访问它,与访问在 [= 中定义的常量的方式完全相同11=].

从逻辑上考虑一下:如果在 class Foo 中定义常量 BAR,则可以使用 Foo::BAR 访问它。如果在 class Qux 中定义常量 BAR,则可以使用 Qux::BAR 访问它。如果您在 Foo 的单例 class 中定义一个常量 BAR,您可以使用... ???

访问它