2014-01-05 161 views
0

使用Ruby 1.9.2,我希望我的DictionaryPresenter類擴展Enumerable,但我在each方法中出現錯誤。錯誤是dictionarynil,即使它在initialize中正確分配。爲什麼這個實例變量忽然有nil的值?

我認爲這與使用dictionary的屬性方法有關,而不是直接使用實例變量@dictionary。我讀過你應該儘可能地用屬性方法替換實例變量的使用,這就是我所做的。

class DictionaryPresenter 
    include Enumerable 
    attr_accessor :dictionary 
    private :dictionary 
    def initialize(collection) 
    dictionary = dictionary_hash 
    collection.each do |element| 
     dictionary[element[0].capitalize] << element 
    end 
    p 'dictionary has been filled. it is' 
    p dictionary 
    end 
    def dictionary_hash 
    ('A'..'Z').reduce({}) do |hash, letter| 
     hash[letter] = [] 
     hash 
    end 
    end 
    def each(&blk) 
    p 'in each' 
    p dictionary 
    dictionary.each(&blk) 
    end 
end 
p DictionaryPresenter.new(['abba', 'beegees']).map{ |a| a } 

輸出

"dictionary has been filled. it is" 
{"A"=>["abba"], "B"=>["beegees"], "C"=>[], "D"=>[], "E"=>[], "F"=>[], "G"=>[], "H"=>[], "I"=>[], "J"=>[], "K"=>[], "L"=>[], "M"=>[], "N"=>[], "O"=>[], "P"=>[], "Q"=>[], "R"=>[], "S"=>[], "T"=>[], "U"=>[], "V"=>[], "W"=>[], "X"=>[], "Y"=>[], "Z"=>[]} 
"in each" 
nil 
anki.rb:22:in `each': undefined method `each' for nil:NilClass (NoMethodError) 
    from anki.rb:25:in `map' 
    from anki.rb:25:in `<main>' 

回答

1

在你的構造函數,你必須使用self.dictionary = dictionary_hash代替dictionary = dictionary_hash

您的版本dictionary = ...在構造函數中創建了一個本地變量,併爲其賦值;它實際上並不使用您定義的attr_accessor。類方法中的所有變量賦值都是如此。如果要使用setter(或者使用def field=明確定義的方法或通過attr_accessor :field),則需要使用self.field =而不是簡單地使用field =

+0

謝謝,就是這樣!我試圖不使用實例變量來重載它! – ben

+0

你能解釋一下你的意思嗎?「在類方法中的所有變量賦值都是這樣。」?也許值得注意的是,另一種表示它是setter的方法是'send(:dictionary =,dictionary_hash)',或者你可以直接引用實例變量('@dictionary = ..')。一個小點:初始化只是一個常規方法,而不是構造函數('new'可能不是,但它更接近)。 –

相關問題