我在Ruby中做了一些元编程,我需要在模块内动态生成一个兄弟类。这样做,我想在模块上调用const_set,但我不知道在运行时调用哪个模块常量。一个例子:
给定课程
Foo::Bar::Baz
Foo::Quox::Quack
我希望能够调用这样的函数(这里过于简化):
def generate_from klass
mod = klass.enclosing_module # <- THIS LINE is the one I need to figure out
mod.const_set("GeneratedClassName", Class.new)
end
以及我希望在使用Baz
进行调用时最终得到的是一个定义为
Foo::Bar::GeneratedClassName
和嘎嘎,我想要
Foo::Quox::GeneratedClassName
我知道的唯一方法是拆分klass.name,然后在这些字符串上重复调用const_get,进行constantized。有谁知道更优雅的方式?
答案 0 :(得分:18)
这应该让你走上正轨:
module Foo
module Bar
class Baz
def initialize
@nesting = Module.nesting
end
def enclosing_module
@nesting.last
end
end
end
end
puts Foo::Bar::Baz.new.enclosing_module #=> Foo
相关文件:
答案 1 :(得分:10)
知道了。 ActiveSupport有这个Ruby扩展,Module#parent。这对我的使用来说已经足够了。
答案 2 :(得分:0)
在 Rails 中,您可以组合使用 deconstantize 和 constantize。
'Foo::Bar::Baz'.deconstantize.constantize # => Foo::Bar
所以在类的方法中可以这样使用:
self.class.name.deconstantize.constantize