我试图让Matz和Flanagan的"Ruby编程语言"元编程章节进入我的脑海,但我无法理解我想出的以下代码片段的输出:

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返回类的常量列表(如A.constants的输出所示).

A的常数显示在模块中.常数.如何获取模块类定义的常量列表?

百州

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

既然A继承了Module.constants的实现,那么它在基类型和派生类型中的行为有什么不同?

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

Note: If you're using Ruby 1.9, 100 would return an array of symbols instead of strings.

推荐答案

问得好!

您的困惑是因为类方法Module.constants隐藏了Module的实例方法Module#constants.

在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

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

Edit:刚刚更改了官方文件以正确反映这一点...

Ruby相关问答推荐

当Ruby `Complex` 类除了`==` 之外没有任何关系运算符时,它的祖先怎么能有`Comparable`?

.nil?、.blank? 之间的区别?和.empty?

Ruby: initialize() vs 类体(class body)?

为什么在 Ruby 中将 0 视为 True?

Sublime Text 2 中的 RubyTest

Python 是否在 Ruby 中进行类似于字符串 #{var}的变量插值?

如何让 Ruby 解析时间,就好像它在不同的时区一样?

如何仅从 Gemfile 中查看依赖关系树?

STDERR.puts 与 Ruby 中的 puts 有何不同?

Jekyll - 找不到命令

如何在Ruby中对数组中对象的属性求和

如何在 ruby​​ 中进行命名捕获

Sublime Text 2 控制台输入

如何让 Ruby 1.9 成为 Ubuntu 上的默认 Ruby?

为什么 Ruby 无法验证 SSL 证书?

判断散列的键是否包含所有键集

正则表达式,如何匹配多行?

为什么在安装 gem 时出现权限被拒绝错误?

Ruby:捕获异常后继续循环

如何使用 minitest 运行所有测试?