for some reason I'm getting
NameError: undefined local variable or method `states' for main:Object
though states is clearly defined. What is going on here?
In irb I added states in and accessed it fine using states[:CA] but when I put it in a method I got that error.
states = {
CA: 'California',
FL: 'Florida',
MI: 'Michigan',
NY: 'New York',
OR: 'Oregon',
}
states[:CO] = 'Colorado'
states[:HI] = 'Hawaii'
cities = {
CA: ['Alameda', 'Apple Valley', 'Exeter'],
FL: ['Exeter', 'Amelia Island', 'Bunnell'],
MI: ['Ann Arbor', 'East China', 'Elberta'],
NY: ['Angelica', 'Apalachin', 'Canadice'],
OR: ['Amity', 'Boring', 'Camas Valley'],
CO: ['Blanca', 'Crestone', 'Dillon', 'Fairplay'],
HI: ['Kailua', 'Hoopili', 'Honolulu'],
}
def describe_state state
puts state
description = "#{state.to_s} is for #{states[state]}."
description << " It has #{citites[state].length} major cities:"
cities[state].each do |x| ' ' << description end
end
puts describe_state :CA
The method can't access the outside variables. You could use instance variables instead. From the documentation:
Example:
(I've fixed a minor bug in
describe_state
)states
is a local variable (because it starts with a lowercase letter). Local variables are local to the scope they are defined in (that's why they are called local variables, after all). So,states
is defined in the scope of the script, but not in the scope of the methoddescribe_state
.Method scopes don't nest, the only scopes that do nest are block scopes, so you would need to use a block. Thankfully, there is a method called
define_method
which creates a method from a block:states and cities are not defined in the function pass them in like
will work