Undefined Local Variable for Hash in Method Ruby

Undefined local variable for hash in method ruby

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 method describe_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 = {
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'],
}

define_method(:describe_state) do |state|
"#{state} is for #{states[state]}. " \
"It has #{cities[state].length} major cities: #{cities[state].join(', ')}"
end

puts describe_state :CA
#=> CA is for California. It has 3 major cities: Alameda, Apple Valley, Exeter

Undefined local variable or method for a Hash for main:Object (NameError)

If you are trying to use closures, then, function defined using def does not support closure behavior - it does not remember the variables bound outside its definition.

In your case, you can change variable pushups to @pushups to make it instance variable.

Alternatively you may have to use lambda or equivalent. A simplified example is shown below that shows how you can access pushups within a lambda.

Sample code

pushups = {"2015-04-16-10:05:01" => 25, "2015-04-10-10:05:01" => 150, "2015-04-11-10:05:01" => 99 }

l = ->(timestamp) do
p pushups
end

l.call ("2015-04-16-10:05:01")

Output

{"2015-04-16-10:05:01"=>25, "2015-04-10-10:05:01"=>150, "2015-04-11-10:05:01"=>99}

Reference: https://softwareengineering.stackexchange.com/questions/180579/what-is-a-closure-and-how-is-it-implemented-in-ruby

Ruby: Undefined local variable or method

Try

puts "Name?, eg. Willow Rosenberg"
name = gets.chomp
number = rand(1000..9000) + 1
data = [
{
name: name,
number: number,
email: name.split(' ').last + number.to_s[-3, 3] + "@btvs.com"
}
]
puts data

Ruby on Rails undefined local variable or method in console

There are 2 things that could be happening. First, you meant to list Article.all, referencing the class. Second, you're referencing article.all as a array, in which case it hasn't been defined as such in your code.

Also, please don't post images of code. Just copy/paste and use the code formatting tools. It really helps us understand what is going on.

Also, it helps to give as much background as possible, meaning what the code is supposed to do, why you're doing it, etc. The more thorough you are, the more helpful we can be.

A Ruby NameError, undefined local variable, was defined

Methods introduce new scope. They are not closures: one should not expect that local variables from the parent scope would be accessible there in the nested scope.

Solution 1: Use constant

POSTAL_CODES = {
V: "British Columbia",
# SKIPPED
B: "Nova Scotia"
}


def lookup_code(postal_code)
territory = POSTAL_CODES.fetch(postal_code[0].upcase.to_sym)
puts "Your address is in #{territory}"
end

Solution 2: Use an instance variable

Despite that you have no class, there is main, which is a special instance of Object, always defined:

@postal_codes = {
V: "British Columbia",
# SKIPPED
B: "Nova Scotia"
}


def lookup_code(postal_code)
territory = @postal_codes.fetch(postal_code[0].upcase.to_sym)
puts "Your address is in #{territory}"
end

Solution 3: Use a global variable

$postal_codes = {
V: "British Columbia",
# SKIPPED
B: "Nova Scotia"
}


def lookup_code(postal_code)
territory = $postal_codes.fetch(postal_code[0].upcase.to_sym)
puts "Your address is in #{territory}"
end

Solution 4: Abuse OOP

One might (bah!) create a class here and use it’s instance:

class Lookup
def postal_codes
@postal_codes ||= {
V: "British Columbia",
# SKIPPED
B: "Nova Scotia"
}
end

def lookup_code(postal_code)
territory = postal_codes.fetch(postal_code[0].upcase.to_sym)
puts "Your address is in #{territory}"
end
end

Lookup.new.lookup_code("01234")

Solution 5 (credits to @ndn): Inline a hash

def lookup_code(postal_code)
territory = {
V: "British Columbia",
# SKIPPED
B: "Nova Scotia"
}.fetch(postal_code[0].upcase.to_sym)
puts "Your address is in #{territory}"
end

I have a Ruby undefined local variable or method error


Problem

With your current code, you get this error:

undefined local variable or method `chicago' for main:Object (NameError)

because the way you instantiated the Message class:

my_message = Message.new(chicago, tokyo)

chicago and tokyo are interpreted as variable or method that you did not actually define or declare, that's why you got that error.

Solution

I think, you just wanted to pass two string objects (putting chicago and tokyo in the quotes) as the arguments of Message.new call like this:

my_message = Message.new('chicago', 'tokyo')

This will solve your problem.

Hope this makes it clear why you are getting the error and how to solve the problem.



Related Topics



Leave a reply



Submit