2015-06-29 33 views
0

這是一個地址簿的類。我想要能夠調用full_name方法。如果沒有中間名,那麼在名字和姓氏之間不應該有空格。爲什麼Ruby的大寫方法試圖調用自己的空變量?

我正在調用capitalize方法,以便將名稱的第一個字母大寫。當我進入一箇中間的名字就可以正常運行,但如果沒有中間的名字我收到此錯誤:

contact.rb:9:in `middle_name': undefined method `capitalize' for nil:NilClass (NoMethodError) 
    from contact.rb:18:in `full_name' 
    from contact.rb:31:in `<main>' 

這是Contact類:

class Contact 
    attr_writer :first_name, :middle_name, :last_name 

    def first_name 
    @first_name.capitalize 
    end 

    def middle_name 
    @middle_name.capitalize 
    end 

    def last_name 
    @last_name.capitalize 
    end 

    def full_name 
    full_name = first_name 
    if !middle_name.nil? 
     full_name += " " 
     full_name += middle_name 
    end 
    full_name += " " 
    full_name += last_name 
    full_name 
    end 
end 

沒有一箇中間名名稱:

jon = Contact.new 
jon.first_name = "jon" 
jon.last_name = "bell" 
puts jon.full_name 

隨着中間名:

hugo = Contact.new 
hugo.first_name = "hugo" 
hugo.middle_name = "don" 
hugo.last_name = "boss" 
puts hugo.full_name 
+0

用戶肯定會給出的強制屬性是什麼? –

+0

如果你使用空字符串進行初始化,那麼這不會是一個問題,你可以像這樣定義full_name'def full_name; [first_name,middle_name,last_name] .map(&:大寫).join('');結尾' – engineersmnky

+0

但是必須定義三個空字符串...... :( –

回答

1

由於您呼叫middle_name的名稱,以及該FULL_NAME方法。 因此,無論您是否提供中間名稱,都會調用該方法。

請改變你的類定義是這樣 -

class Contact 
    attr_writer :first_name, :middle_name, :last_name 

    def first_name 
     @first_name.capitalize if @first_name 
    end 

    def middle_name 
     @middle_name.capitalize if @middle_name 
    end 

    def last_name 
     @last_name.capitalize if @last_name 
    end 

    def full_name 
     full_name = first_name 
     if !middle_name.nil? 
     full_name += " " 
     full_name += middle_name 
     end 
     full_name += " " 
     full_name += last_name 
     full_name 
    end 
    end 
1

您收到錯誤的原因是您在檢查無值時調用方法middle_name。在!middle_name.nil?

關於這一點,沒有過多的修飾你的代碼,只需更換該方法調用

if [email protected]? 

,它應該只是罰款。

full_name方法應該這樣寫的......

def full_name 
    full_name = first_name 
    if @middle_name 
    full_name += " " 
    full_name += middle_name 
    end 
    full_name += " " 
    full_name += last_name 
    full_name 
end 

注意,你可以簡單地只是說的if @middle_name代替[email protected]_name.nil?

+0

我收到此錯誤:'contact.rb:5:堆棧層面太深(SystemStackError)' –

+0

這意味着你正在調用一個方法,遞歸調用自己並不停止。 –

0
class Contact 
    attr_writer :first_name, :middle_name, :last_name 

    def first_name 
    @first_name.capitalize if @first_name 
    end 

    def middle_name 
    @middle_name.capitalize if @middle_name 
    end 

    def last_name 
    @last_name.capitalize if @last_name 
    end 

    # The full_name method can be refactored as below... 

    def full_name # If plain Ruby 
    name = [first_name, middle_name, last_name].reject{|name_type| !(name_type =~ /\A[[:space:]]*\z/).nil?} 
    name.join(" ") 
    end 

    def full_name_rails # If Ruby on Rails 
    name = [first_name, middle_name, last_name].reject(&:blank?).join(" ") 
    end 

end 
1

這裏是最乾淨的實施#full_name我能想到的:

def full_name 
    [@first_name, @middle_name, @last_name].reject(&:nil?).map(&:capitalize).join(' ') 
end 

爲了防止String#capitalize使用,我想執行#first_name=,#middle_name=#last_name=爲:

def middle_name=(value) 
    @middle_name = value.capitalize 
end 
# you can now omit the .map(&:capitalize) part from #full_name 
相關問題