Reputation: 3257
This is a class for an address book. I want to be able to call the full_name
method. If there is no middle name then there shouldn't be a space displayed between first and last name.
I am invoking the capitalize
method so that it will capitalize the first letter of the name. When I enter a middle name it runs correctly, but if there is no middle name I receive this error:
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>'
This is the Contact class:
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
Name without a middle name:
jon = Contact.new
jon.first_name = "jon"
jon.last_name = "bell"
puts jon.full_name
With a middle name:
hugo = Contact.new
hugo.first_name = "hugo"
hugo.middle_name = "don"
hugo.last_name = "boss"
puts hugo.full_name
Upvotes: 1
Views: 226
Reputation: 3792
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
Upvotes: 0
Reputation: 1159
Here is the cleanest implementation of #full_name
I can think of :
def full_name
[@first_name, @middle_name, @last_name].reject(&:nil?).map(&:capitalize).join(' ')
end
To prevent String#capitalize
to be used, I would implement #first_name=
, #middle_name=
and #last_name=
as this :
def middle_name=(value)
@middle_name = value.capitalize
end
# you can now omit the .map(&:capitalize) part from #full_name
Upvotes: 1
Reputation: 19839
The reason you're getting the error is because you're calling the method middle_name
when you're checking for a nil value. on !middle_name.nil?
On that note, without too many modifications to your code, simply replace that method call to
if [email protected]?
and it should work just fine.
Your full_name
method should read like this...
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
Note, you can simply just say if @middle_name
instead of !@middle_name.nil?
Upvotes: 1
Reputation: 370
Since in the full_name method you are calling middle_name name as well. So whether or not you provide a middle name it will call that method.
Please change your class definition like this -
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
Upvotes: 1