/ / Definindo variáveis ​​de instância em diferentes objetos da mesma classe - ruby

Configurando variáveis ​​de instância em objetos diferentes da mesma classe - ruby

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 № 1

Mudar 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 persons " partners 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