12

2 つのクラス Foo と Foo Sub があり、それぞれが異なるファイル foo.rb と foo_sub.rb にあるとします。

foo.rb:

require "foo_sub"
class Foo
    def foo
        FooSub.SOME_CONSTANT
    end
end

foo_sub.rb:

require "foo"
class FooSub < Foo
    SOME_CONSTANT = 1
end

循環依存のため、これは機能しません。一方のクラスを他方なしで定義することはできません。私が見たさまざまな解決策があります。そのうちの 2 つを避けたいと思います。つまり、それらを同じファイルに入れ、循環依存関係を削除することです。したがって、私が見つけた他の唯一の解決策は、前方宣言です。

foo.rb:

class Foo
end
require "foo_sub"
class Foo
    def foo
        FooSub.SOME_CONSTANT
    end
end

foo_sub.rb

require "foo"
class FooSub < Foo
    SOME_CONSTANT = 1
end

残念ながら、3 つのファイルがある場合、同じことを行うことはできません。

foo.rb:

class Foo
end
require "foo_sub_sub"
class Foo
    def foo
        FooSubSub.SOME_CONSTANT
    end
end

foo_sub.rb:

require "foo"
class FooSub < Foo
end

foo_sub_sub.rb:

require "foo_sub"
class FooSubSub < FooSub
    SOME_CONSTANT = 1
end

foo_sub.rb が必要な場合、FooSub は foo_sub_sub.rb 内の初期化されていない定数です。それらを同じファイルに入れたり、循環依存関係を削除したりせずに、これを回避する方法はありますか?

4

3 に答える 3

15

スーパークラスからサブクラスにアクセスする必要がある場合、モデルが壊れている可能性があります (つまり、1 つのクラスである必要があります)。

とはいえ、明らかな解決策がいくつかあります。

1) foo ファイルを必要とするファイルを作成するだけです。

all_foos.rb:

require "foo.rb"
require "foo_sub.rb"

foo.rb と foo_sub.rb から require を削除します。

2) foo.rb から require を削除します

3) foo_sub.rb から require を削除し、クラス定義の後の foo.rb に require を入れます。

Ruby は C++ ではありません。 Foo#foo() を呼び出すまで FooSub.SOME_CONSTANT について文句を言うことはありません;)

于 2008-12-28T14:04:09.767 に答える