6

Ruby では、モジュール/クラスを他のモジュール/クラスにネストできます。私が望むのは、ファイルまたはクラス内にいくつかの宣言を追加して、ネストされたクラスを短い名前で参照できるようにすることです。たとえば、Java や C# などで使用Innerするように getに使用しOuter::Innerます。構文は次のようになります。

module Outer
  class Inner; end
  class AnotherInner; end
end
class C
  import Outer: [:Inner, :AnotherInner]
  def f
    Inner
  end
end

単純化した実装は次のようになります。

class Class
  def import(constants)
    @imported_constants = 
      (@imported_constants || {}).merge Hash[
        constants.flat_map { |namespace, names|
          [*names].map { |name| [name.to_sym, "#{namespace}::#{name}"] }
        }]
  end

  def const_missing(name)
    const_set name, eval(@imported_constants[name] || raise)
  end
end

Railsまたはいくつかのgemに、Railsの自動ロードメカニズムと互換性がありながら同様のインポートを行う確実な実装はありますか?

4

1 に答える 1

2
module Outer
  class Inner; end
  class AnotherInner; end
end

class C
  include Outer

  def f
    Inner
  end
end

C.new.f # => Outer::Inner

覚えておいてください: Ruby にはネストされたクラスのようなものはありません。クラスは、他のオブジェクトと同様に単なるオブジェクトであり、他のオブジェクトと同様に変数に割り当てられます。この特定のケースでは、「変数」はモジュール内で名前空間を持つ定数です。そして、他の定数と同じように、その定数を別のモジュール (またはクラス) の名前空間に追加しincludeます。つまり、モジュールを ing します。

于 2012-08-09T21:24:47.337 に答える