2017-06-05 14 views
0

Ich möchte auf ein Objekt verweisen, während es instanziieren, um es an ein anderes Objekt zu übergeben, das ich instanziiere. Was ich meine:Erhalten Sie einen Verweis auf ein Objekt, während es instanziiert

A.new(B.new(self)) 

In diesem Fall self würde den Umfang beziehen, in dem ich eigentlich A.new Aufruf bin. Was ich will, ist für self (oder was auch immer anderes Schlüsselwort) auf das neu instanziierte Objekt A beziehen, so dass B einen Verweis auf A haben würde. Gibt es eine Möglichkeit, dies zu tun?

+1

es nennt diese Art und Weise eine kreisförmige Referenz wäre, da die A-Instanz benötigt wird, B zu instanziiert, was für A, etc. benötigt wird. Sie könnten das B.new jedoch in A # initialisieren. –

+0

Wenn Sie an diesem Punkt sind, gibt es wahrscheinlich ein besseres Design, das Sie nicht sehen. Versuchen Sie, Ihr Beispiel etwas mehr mit dem Beispielcode auszuarbeiten. – Rogue

+0

Will 'B.new (A.new)', nicht ausreichen? – progfan

Antwort

2

Die Art und Weise Sie es geschrieben haben (A.new(B.new(self))) ist unmöglich aufgrund eines zirkuläre Referenz. Um eine Instanz von A zu erstellen, benötigen Sie eine Instanz von B; Um die Instanz B zu erstellen, benötigen Sie die Instanz A.

Es gibt einige Möglichkeiten, die Implementierung zu optimieren, um dies zu ermöglichen, aber Sie müssen zuerst dieses Huhn-und-Ei-Problem zwischen A und B lösen. Zum Beispiel:

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

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

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

Beachten Sie, dass in dem obigen Code wird aerste initialisiert. Es wird nur im Bereich nach das Objekt erstellt worden ist.

Oder hier ist eine andere Art und Weise:

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

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

A.new 

Wie oben, wird die Instanz von Aersten geschaffen. Aber dieses Mal habe ich die gesamte Initialisierung auf einmal gemacht, anstatt sie innerhalb des gemeldeten Anrufs new() aufzubauen.

Ein letztes Beispiel:

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) } 

In diesem Beispiel habe ich voll initialisiert a vor seinem Attribut b definieren. Dies könnte genauso gut in zwei Zeilen Code geschrieben wurde, mit einer regulären Variable anstelle der Schließung:

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

Danke Tom. Ich erkannte, dass ich kurz nach der Veröffentlichung ein Problem mit meinem Design hatte. Ich löste es so: 'A.new (B)' Und dann in 'A' initialisierte ich' B' wie ich wollte. –

Verwandte Themen