Techioz Blog

Ruby: クラスの外側のモジュール const を取得する方法はありますか?

概要

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

そしてQuackで、私は欲しいです

Foo::Quox::GeneratedClassName

私が知っている唯一の方法は、klass.name を分割し、定数化されたそれらの文字列に対して const_get を繰り返し呼び出すことです。もっとエレガントな方法を知っている人はいますか?

解決策

これで軌道に乗るはずです。

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