在运行时继承一个新的类方法
在 Ruby 中,
对于检查类很有用:
> Numeric.constants(false)
=> [:KILOBYTE, :MEGABYTE, :GIGABYTE, :TERABYTE, :PETABYTE, :EXABYTE]
> Object.constants(false)
=> [:Object, :Module, ...]
这是在 Module
:
> Object.method(:constants)
=> #<Method: Class(Module)#constants>
我想添加另一种方法来打印包含所有常量及其值的哈希值。这是到目前为止的结果:
def Module.constants_hash(inherit=true)
self.constants(inherit).inject({}) do |hash, constant|
hash[constant] = self::const_get(constant)
hash
end
end
这适用于Module
(尽管它没有常量,因此结果只是一个空哈希),但是它不是继承的:
> Object.constants_hash(false)
NoMethodError: undefined method `constants_hash' for Object:Class
from (pry):117:in `<main>'
我当然可以将代码中的类名更改为例如Object
以使调用起作用,但是是否可以使所有依赖模块也继承新方法?换句话说,是否可以在运行时添加一个方法,然后由需要
修改后的类的类继承?
我宁愿不要重载原始的 Module.constants
,以避免更改 API。
In Ruby, <ClassName>.constants
is useful to inspect classes:
> Numeric.constants(false)
=> [:KILOBYTE, :MEGABYTE, :GIGABYTE, :TERABYTE, :PETABYTE, :EXABYTE]
> Object.constants(false)
=> [:Object, :Module, ...]
This is defined in Module
:
> Object.method(:constants)
=> #<Method: Class(Module)#constants>
I'd like to add another method to print a hash with all the constants and their values. Here's the result so far:
def Module.constants_hash(inherit=true)
self.constants(inherit).inject({}) do |hash, constant|
hash[constant] = self::const_get(constant)
hash
end
end
This works for Module
(although it has no constants, so the result is just an empty hash), but it's not inherited:
> Object.constants_hash(false)
NoMethodError: undefined method `constants_hash' for Object:Class
from (pry):117:in `<main>'
I can of course change the class name in the code to e.g. Object
to make the call work, but is it possible to make all the dependent modules inherit the new method as well? In other words, is it possible to add a method at runtime which is then inherited by classes which require
the modified class?
I'd rather not overload the original Module.constants
, to avoid changing the API.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Object
是Class
类型的实例。Class
类继承自Module
。为了让Object.constants_hash
工作,您需要定义Class
或Module
类的 instance 方法:您编写代码时只需将
constants_hash
添加到Module
实例(类型为Class
)的单个类,这就是原因你没有得到预期的结果。Object
is an instance of typeClass
.Class
class is inherited fromModule
. In order forObject.constants_hash
to work, you need to define instance method ofClass
orModule
classes:In you code you just add
constants_hash
to a singleton class ofModule
instance (of typeClass
), this is why you don't get expected result.通过在模块中声明此方法,然后根据需要将其混合到每个上下文中,您可能会有更好的运气:
请注意,使用
Hash[]
而不是inject({ }) 在这种情况下似乎确实效果更好。
You might have better luck by declaring this method in a module, then mixing it in to each context as required:
As a note, using
Hash[]
instead ofinject({ })
does seem to work better in cases like this.