2

次の例でエラーが発生するのはなぜですか?

class ClassA
  class ClassB
  end
  class ClassC
    def test
      ClassB.new
    end
  end
end

p ClassA::ClassC.new.test # => #<ClassA::ClassB:0x0000010103f860>

class ClassA
  class ClassD
    def test
      ClassB.new
    end
  end
end

p ClassA::ClassD.new.test # => #<ClassA::ClassB:0x0000010103f010>

class ClassA::ClassE
  def test
    ClassB.new
  end
end

p ClassA::ClassE.new.test # => NameError: uninitialized constant ClassA::ClassE::ClassB

ClassEを入力するのではなく、を作成する別の方法はありますclass ClassA; class ClassEか?

4

2 に答える 2

1

はい、そうです、テストメソッドを定義して返す場合ClassA::ClassB.new:-)

const_missingを呼び出すようにいじることもできますClassA.const_get

それ以外の場合ClassBは現在のスコープにありません。その時点では と のみClassA::ClassEですObject。を最初に開いたとき、 の検索は最初に で行われ、次にClassA(見つかった場所) で行われ、 も検索されます。ClassEClassBClassA::ClassEClassAObject

于 2010-07-22T20:08:30.340 に答える
0

Marc-André Lafortuneによって提案されたカスタムObject#const_missingメソッドは、次のようになります。

def Object.const_missing(name)
  @looked_for ||= {}
  key = self.to_s + '~' + name.to_s
  raise "Class not found: #{name}" if @looked_for[key] == key
  return @looked_for[key] if @looked_for[key]
  @looked_for[key] = key
  if self.to_s.include? '::'
    klass = Object
    self.to_s.split('::')[0..-2].each do |klass_string|
      klass = klass.const_get klass_string
    end
    return @looked_for[key] = klass.const_get(name) if klass # klass.is_a?(Class)
  end
  raise "Class not found: #{name}"
end

関連する質問:

  1. Ruby は、クラス A::B::C の [:A,:B] のような名前空間パスを提供しますか?
  2. Ruby Object クラスでクラスメソッドを定義した場合、このメソッドを呼び出す子クラスの名前を取得するにはどうすればよいですか?
  3. Rubyで文字列「A::B::C」からクラスオブジェクトを取得するにはどうすればよいですか?
于 2010-07-22T23:05:52.497 に答える