繁体   English   中英

如何通过反射获取Ruby的Module类定义的常量?

[英]How do I get constants defined by Ruby's Module class via reflection?

我试图让Matz和Flanagan的“Ruby Programming Language”元编程章节进入我的脑海,但是我无法理解我梦想的以下代码片段的输出:

p Module.constants.length           # => 88
$snapshot1 = Module.constants       
class A
  NAME=:abc

  $snapshot2 = Module.constants
  p $snapshot2.length               # => 90
  p $snapshot2 - $snapshot1         # => ["A", "NAME"]

end
p Module.constants.length           # => 89
p Module.constants - $snapshot1     # => ["A"]
p A.constants                       # => ["NAME"]

本书指出类方法constants返回类的constants列表(如A.constants的输出中A.constants )。 当我遇到上述奇怪的行为时,我试图获取为Module类定义的常量列表。

A常量出现在Module.constants中。 如何获取Module类定义的常量列表?

文档陈述

Module.constants返回系统中定义的所有常量。 包括所有类和方法的名称

由于AModule.constants继承了它的实现,它在基类和派生类型中的表现如何?

p A.class               # => Class
p A.class.ancestors       # => [Class, Module, Object, Kernel]

注意:如果您使用的是Ruby 1.9, constants将返回符号数组而不是字符串。

好问题!

你的困惑是由于类方法的事实Module.constants隐藏实例方法Module#constantsModule

在Ruby 1.9中,通过添加可选参数解决了这个问题:

# No argument: same class method as in 1.8:
Module.constants         # ==> All constants
# One argument: uses the instance method:
Module.constants(true)   # ==> Constants of Module (and included modules)
Module.constants(false)  # ==> Constants of Module (only).

在上面的示例中, A.constants调用Module#constants (实例方法),而Module.constants调用Module.constants

在Ruby 1.9中,您希望调用Module.constants(true)

在Ruby 1.8中,可以在Module上调用实例方法#constants 您需要获取实例方法并将其绑定为类方法(使用不同的名称):

class << Module
  define_method :constants_of_module, Module.instance_method(:constants)
end

# Now use this new class method:
class Module
   COOL = 42
end
Module.constants.include?("COOL")  # ==> false, as you mention
Module.constants_of_module         # ==> ["COOL"], the result you want

我希望我能够将1.9功能完全反向移植到1.8 for backports gem,但我想不出在Ruby 1.8中只获取模块常量的方法,不包括继承的模块。

编辑 :刚刚更改了官方文档以正确反映这一点......

在Marc的回应之后,我不得不回到我的思考洞穴一段时间。 使用更多代码片段进行修补,然后再进行更多操作。 最后,当Ruby的方法分辨率似乎有意义时,将其写成博客文章,这样我就不会忘记。

符号:如果A“A的本征

A.constants ,方法解析(请参阅我博客文章中的图像以获得视觉辅助)按顺序查找以下位置

  • MyClass"Object"BasicObject" (单例方法)
  • Class (实例方法)
  • Module (实例方法)
  • Object (实例方法)和内核
  • BasicObject (实例方法)

Ruby找到实例方法Module#constants

Module.constants ,Ruby会查看

  • Module"Object"BasicObject" (单例方法)
  • Class (实例方法)
  • Module (实例方法)
  • Object (实例方法)和内核
  • BasicObject (实例方法)

这次,Ruby在Module".constants找到了singleton / class方法,正如Marc所说。

模块定义了一个影响实例方法的单例方法。 单例方法返回所有已知常量,而实例方法返回当前类及其祖先中定义的常量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM