2017-06-05 16 views
0

インスタンス化中にオブジェクトを参照して、インスタンス化している別のオブジェクトにそのオブジェクトを渡したいとします。私は何を意味する:この場合、インスタンス化中のオブジェクトへの参照を取得する

A.new(B.new(self)) 

selfは私が実際にA.newを呼んでいるいる範囲を参照することになります。私が欲しいのは、新たにインスタンス化されたAオブジェクトを参照するためにself(または他のどのようなキーワードでも)です。したがって、BAへの参照を持ちます。これを行う方法はありますか?

+1

インスタンスがBをインスタンス化するために必要とされるので、この方法は、円形の基準となり、それを呼び出すために、これはAなどに必要です。B.newをA#に初期化することもできます。 –

+0

この時点では、あなたが見ていないより優れたデザインがおそらくあります。いくつかのサンプルコードであなたのサンプルをもう少し詳しく調べてみてください。 – Rogue

+0

'B.new(A.new)'は不十分でしょうか? – progfan

答えて

2

あなたはそれを書かれている方法(A.new(B.new(self))循環参照による、不可能です。

Aのインスタンスを作成するには、Bのインスタンスが必要です。 Bのインスタンスを作成するには、Aのインスタンスが必要です。

これを可能にするために実装を調整する方法はいくつかありますが、最初にABの間のこの鶏と卵の問題を解決する必要があります。例えば:上記のコードでは、a最初に初期化されていること

class A 
    def initialize 
    @b = yield(self) 
    end 
end 

class B 
    def initialize(a) 
    @a = a 
    end 
end 

A.new { |a| B.new(a) } 

注意。オブジェクトが作成された後にはの範囲内でのみ返されます。

それとも、ここで別の方法があります:上記のよう

class A 
    def initialize 
    @b = B.new(self) 
    end 
end 

class B 
    def initialize(a) 
    @a = a 
    end 
end 

A.new 

Aのインスタンスが最初を作成されています。しかし、今回は、new()メッシュコール内に構築するのではなく、すべての初期化を1回で済ませました。

最後にもう一つの例:この例では

class A 
    attr_writer :b 
    def initialize 
    end 
end 

class B 
    def initialize(a) 
    @a = a 
    end 
end 

A.new.tap { |a| a.b = B.new(a) } 

、私はが完全にbのその属性を定義する前にaを初期化しています。これは同じように簡単に代わりクロージャの正規変数と、2行のコードで書かれている可能性:

a = A.new 
a.b = B.new(a) 
+0

ありがとうございます。私はそれを投稿した直後に私のデザインに問題があることに気付きました。私はこれを次のように解決しました: 'A.new(B)' そして 'A'の中で、私が望むように' B'を初期化しました。 –

関連する問題