Reputation: 1105
I have a method I wish to use, to be make my code a little more legible (in my opinion)
My code:
def format_chosen_address(address)
# Add country before the postcode
postcode = address.split("\n").last
country = postcode.is_welsh? ? 'WALES' : 'ENGLAND'
address.split("\n").insert(-2, country).join(' ')
end
def is_welsh?
welsh_postcodes = ['SA1 6AZ', 'SA7 9BR', 'CF10 1AX']
welsh_postcodes.include? self
end
I get the following exception:
NoMethodError: undefined method `is_welsh?' for "SA1 6AZ":String
Where have I gone wrong because thought self and boolean methods could be used this way?
I can get it to work if I do the following, but it doesn't read as nice to me.
def format_chosen_address(address)
# Add country before the postcode
postcode = address.split("\n").last
country = is_welsh?(postcode) ? 'WALES' : 'ENGLAND'
address.split("\n").insert(-2, country).join(' ')
end
def is_welsh?(postcode
welsh_postcodes = ['SA1 6AZ', 'SA7 9BR', 'CF10 1AX']
welsh_postcodes.include? postcode
end
Upvotes: 0
Views: 67
Reputation: 21160
You could also use a module to add certain helpers to the singleton class of the string. Meaning that they are only added for that specific instance of String
and not for all strings.
module PostcodeHelpers
def is_welsh?
welsh_postcodes = ['SA1 6AZ', 'SA7 9BR', 'CF10 1AX']
welsh_postcodes.include?(self)
end
def country
is_welsh? ? 'WALES' : 'ENGLAND'
end
end
def format_chosen_address(address)
*lines, postcode = address_lines(address)
[*lines, postcode.country, postcode].join(' ')
end
private # assuming you are in class or module context
def address_lines(address)
*lines, postcode = address.split("\n")
# Default to empty string since you don't want to extend nil by accident.
postcode ||= ''
postcode.extend(PostcodeHelpers)
[*lines, postcode]
end
Like you can see this might be overkill for this scenario and produces quite a bit of additional code.
Upvotes: 0
Reputation: 2783
You can define the is_welsh?
inside the String class like this:
class String
def is_welsh?
welsh_postcodes = ['SA1 6AZ', 'SA7 9BR', 'CF10 1AX']
welsh_postcodes.include? self
end
end
But it doesn't really make sense for every String to have a method that tells if it's Welsh or not. So the better option is to make it a method that takes a parameter (like your second example in the question):
def is_welsh?(postcode)
welsh_postcodes = ['SA1 6AZ', 'SA7 9BR', 'CF10 1AX']
welsh_postcodes.include? postcode
end
Upvotes: 1
Reputation: 107142
The problem is that you are calling postcode.is_welsh?
which means you are calling the method is_welsh?
on the string, but you didn't define the method on String but within another class.
Actually, I advise adding methods like to the String class. It is too specific to pollute the whole String namespace. Instead, I suggest just leaving that method as a (probably as a private
) helper method and passing the postal code string to it as an argument:
def is_welsh?(postcode)
welsh_postcodes = ['SA1 6AZ', 'SA7 9BR', 'CF10 1AX']
welsh_postcodes.include? postcode
end
and call it like:
country = is_welsh?(postcode) ? 'WALES' : 'ENGLAND'
Upvotes: 2