Vamos dizer que eu tenho uma aula chamada Person
e pessoa tem um atributo chamado partner
. Quando eu chamo partner=
em um dos Person
objetos, eu quero definir o @partner
variável de instância de ambos os objetos. Aqui está um exemplo com sintaxe inválida:
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
Respostas:
2 para resposta № 1Mudar o attr_reader
para um attr_accessor
e adicione um método auxiliar:
class Person
attr_accessor :partner
def link_partners(person)
@partner = person
person.partner = self
end
end
Atualização para visibilidade. Baseado na sugestão de Frederick abaixo. Isso é um pouco mais detalhado, mas impedirá que o parceiro seja definido diretamente:
class Person
protected
attr_writer :partner
public
attr_reader :partner
def link_partners(person)
@partner = person
person.partner = self
end
end
Ambas as implementações funcionam assim:
p1, p2 = Person.new, Person.new
p1.link_partners(p2)
# p2.link_partners(p1)
1 para resposta № 2
Você poderia fornecer um método auxiliar protegido que é chamado por seu partner=
método para fazer o trabalho real. Uma vez que não pode ser chamado por "estranhos", todos os seus cheques e saldos podem ser mantidos em sua implementação de 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 para resposta № 3
Não importa, acabei de descobrir 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 para a resposta № 4
Em teoria, você poderia fazer isso da seguinte maneira:
def partner=(person)
@partner = person
person.instance_variable_set(:@partner, self)
end
No entanto, eu consideraria isso mágica. (Isso não é uma coisa boa.) Em vez disso, faça o attr_reader
em um attr_accessor
e escrever um método diferente para definir dois person
s " partner
s um para o outro.
0 para a resposta № 5
Isso resolverá seu problema com o conjunto recursivo e parece melhor do que sua solução:
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