Ruby:有没有办法获得一个类的封闭模块const?

时间:2011-06-01 21:34:53

标签: ruby metaprogramming

我在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。有谁知道更优雅的方式?

3 个答案:

答案 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

相关文件:

http://ruby-doc.org/core/classes/Module.html#M000441

答案 1 :(得分:10)

知道了。 ActiveSupport有这个Ruby扩展,Module#parent。这对我的使用来说已经足够了。

答案 2 :(得分:0)

在 Rails 中,您可以组合使用 deconstantizeconstantize

'Foo::Bar::Baz'.deconstantize.constantize # => Foo::Bar

所以在类的方法中可以这样使用:

self.class.name.deconstantize.constantize