/ / Nastavenie premenných inštancie na rôznych objektoch tej istej triedy - rubín

Nastavenie premenných inštancie na rôzne objekty tej istej triedy - rubín

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ď č. 1

Zmeniť 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 persons " partners 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