2013-07-21 84 views
0

假設我有一個名爲Person的類,並且人有一個名爲partner的屬性。當我在Person對象之一上調用partner=時,我想要設置兩個對象的@partner實例變量。下面是無效的語法的例子:在同一類的不同對象上設置實例變量

class Person 

    attr_reader :partner 

    def partner=(person) 

    # reset the old partner instance variable if it exists 
    [email protected] = nil if partner 

    # set the partner attributes 
    @partner = person 
    [email protected] = self 
    end 
end 

回答

0

沒關係,我只是發現了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

你可以這樣肯定地訪問實例變量getter和setter,特別是如果你想讓setter可以被私人訪問的話。就你而言,可能有更好的方法來實現你想要的。我想我需要在這個問題上更加清晰。 –

2

更改attr_readerattr_accessor,並添加一個輔助方法:

更新的知名度。根據弗雷德裏克的建議。這是一個有點冗長,但會阻止夥伴被直接設置:

class Person 
    protected 
    attr_writer :partner 

    public 
    attr_reader :partner 

    def link_partners(person) 
    @partner = person 
    person.partner = self 
    end 
end 

兩種實現是這樣的:

p1, p2 = Person.new, Person.new 
p1.link_partners(p2) 
# p2.link_partners(p1) 
+0

我真的不知道該怎麼解決我的問題。你能否詳細說明一下? – LandonSchropp

+0

對不起,我正在闡述,但是在找到setter之前沒有到達那裏。 –

+0

我的解決方案的主要問題是,任何人都可以直接打電話給person.partner,並且只會設置該人的合作伙伴。 –

0

從理論上講,你可以這樣做如下:

def partner=(person) 
    @partner = person 
    person.instance_variable_set(:@partner, self) 
end 

不過,我認爲這是魔術。 (這不是一件好事。)相反,將attr_reader設置爲attr_accessor,然後編寫一個不同的方法將兩個person s'partner設置爲彼此。

+0

我想我不覺得它很神奇,因爲這是我期望的行爲。文檔肯定會幫助:) – LandonSchropp

0

這將解決您的問題遞歸集,看起來比你更好的解決方案:

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 
1

你可以提供得到由你partner=方法稱爲做實際的工作中受保護的幫助方法。因爲它不能被「外人」,被稱爲所有的檢查和平衡的可以在實施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 
相關問題