2017-10-11 57 views
1

我無法使用#buy_fish添加到實例的#pets散列。它成功返回正在添加到散列的內容,但散列不會更改。無法添加到實例的散列(ruby)

所有人類別

class Owner 
    attr_accessor :name 

    def initialize(name) 
    pets 
    end 

    def pets 
    @pets = {cats: [], dogs: [], fishes: []} 
    end 

    def buy_fish(name) 
    self.pets[:fishes] << Fish.new(name) 
    end 
end 

魚類

class Fish 
    attr_reader :name 

    def initialize(name) 
    @name = name 
    end 
end 
+3

每次調用'pets'都會爲'@ pets'分配一個新的散列。將任務移入'initialize'或使用'@pets || = {...}'。 – Stefan

+3

另外,我相信你想做'self.pets [:fishes] .push(Fish.new(name))''。否則,你只需每次設置單個「Fish」實例的關鍵字。 – John

+0

謝謝Stefan。這工作。我還沒有學過|| =呢。有沒有另一種方法來做到這一點?我覺得這是一個騙子的出路,因爲我寫了糟糕的代碼? 另外,約翰,我只是注意到,當修復代碼。不管怎麼說,還是要謝謝你! –

回答

1

@馬特的解決方案工作。

我只是補充一點,我沒有理由爲什麼pets的評價應該是懶惰的。因此,您可以在構造函數中將它內聯並添加一個閱讀器:

class Owner 
    attr_accessor :name 
    attr_reader :pets 

    def initialize(name) 
    @pets = {cats: [], dogs: [], fishes: []} 
    end 

    def buy_fish(name) 
    @pets[:fishes] << Fish.new(name) 
    end 
end 
1

正如斯蒂芬指出的那樣,每次調用pets asssigns一個新的哈希至@pets。在寵物方法中加入||=解決了這個問題。

代碼

def pets 
    @pets ||= {cats: [], dogs: [], fishes: []} 
end 
+2

這不是一個「作弊方式」。事實上,這是一種非常常見的紅寶石成語,被稱爲「memoization」。 –

相關問題