Povedzme, že mám triedu s názvom Person
a osoba má prívlastok tzv partner
, Keď zavolám partner=
na jednom z Person
objekty, chcem nastavit @partner
inštančná premenná oboch objektov. Tu je príklad s neplatnou syntaxou:
class Person
attr_reader :partner
def partner=(person)
# reset the old partner instance variable if it exists
partner.@partner = nil if partner
# set the partner attributes
@partner = person
person.@partner = self
end
end
odpovede:
2 pre odpoveď č. 1Zmeniť attr_reader
na attr_accessor
a pridať pomocnú metódu:
class Person
attr_accessor :partner
def link_partners(person)
@partner = person
person.partner = self
end
end
Aktualizácia viditeľnosti. Na základe návrhu Fredericka uvedeného nižšie. Je to o niečo podrobnejšie, ale zabráni sa tomu, aby bol partner nastavený priamo:
class Person
protected
attr_writer :partner
public
attr_reader :partner
def link_partners(person)
@partner = person
person.partner = self
end
end
Obe implementácie fungujú takto:
p1, p2 = Person.new, Person.new
p1.link_partners(p2)
# p2.link_partners(p1)
1 pre odpoveď č. 2
Môžete poskytnúť chránenú pomocnú metódu, ktorú vám zavolá partner=
spôsob vykonania skutočnej práce. Pretože ho nemôžu nazývať „outsideri“, všetky vaše kontroly a zostatky môžu byť zachované pri implementácii partner=
:
class Person
attr_reader :partner
def partner=(person)
@partner.set_partner(nil) if @partner
set_partner(person)
person.set_partner(self) if person
end
def set_partner(person)
@partner = person
end
protected :set_partner
end
0 pre odpoveď č. 3
Nevadí, práve som objavil instance_variable_set
.
class Person
attr_reader :partner
def partner=(person)
# reset the old partner instance variable if it exists
partner.instance_variable_set(:@partner, nil) if partner
# set the partner attributes
@partner = person
person.instance_variable_set(:@partner, self)
end
end
0 pre odpoveď č. 4
Teoreticky by ste to mohli urobiť nasledovne:
def partner=(person)
@partner = person
person.instance_variable_set(:@partner, self)
end
Považoval by som to však za kúzlo. (To nie je dobrá vec.) Namiesto toho urobte attr_reader
do attr_accessor
a napísať inú metódu na nastavenie dvoch person
s " partner
s navzájom.
0 pre odpoveď č. 5
To vyrieši váš problém s rekurzívnou sadou a vyzerá lepšie ako vaše riešenie:
class Partner
attr_reader :partner
def set_partner(person, recursive = true)
# reset previous partner
@partner.set_partner(nil, false) if recursive && @partner
# set new partner
@partner = person
@partner.set_partner(self, false) if recursive
end
alias_method :partner=, :set_partner
end