I have a Ruby undefined local variable or method error - ruby

When I try to run this code:
class Message
##messages_sent = 0
def initialize(from, to)
#from = from
#to = to
##messages_sent += 1
end
end
my_message = Message.new(chicago, tokyo)
I get an error that tells me that one of my parameters is undefined local variable. I was just trying to create an instance using Message, and was curious as to why this was not working. I thought this would work as I am calling the class.

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.

The 'undefined local variable' error is showing up because there's no value associated with chicago or tokyo. If you want to just pass them as strings, wrap them in quotation marks instead, like this:
class Message
##messages_sent = 0
def initialize(from, to)
#from = from
#to = to
##messages_sent += 1
end
end
my_message = Message.new("chicago", "tokyo")

Related

undefined method `gsub' for nil:NilClass ruby

i am a newbie in ruby... I'm trying to convert media into a scorm package using what i found on github but i got an error while trying to run the script in the command prompt undefined method `gsub' for nil:NilClass. I guess it may be due to a defined method. any idea on how i can remove this error ?
dir = ARGV.shift.gsub(/\/+$/, '')
index = nil
media = []
Dir["#{dir}/media/*.json"].each do |file|
id = JSON.parse(File.read(file))
base = file.gsub(/\/media\/.*\.json$/, '')
index = "#{base}/index.html"
name = File.basename file
media.push [name,id]
puts "#{name}: #{id}"
end
As the error says, you are calling the method gsub on an object that is an instance of NilClass, in other words you are calling gsub on nil.
The error message tells you in which method and on which line this happens and how you got to that line of code. You will have to examine the error message to find the place in your code where you are calling gsub on an object that is nil, then you have to examine your code to find out why that object is nil instead of a String as you expect it to.

NoMethodError but did 'require_relative'

I did the 'requir_relative' but still got the NoMethodError.
There are 2 ruby files, under 'run.rb' I have this
class Run
def separate(data)
hash_block = []
(0...data.count).each do |i|
f = data[i].split('|')
hash_block[i] = Hashing.new(f[0].to_i, f[1], f[2], f[3], f[4])
end
hash_block
end
end
and then in the main file, I did these:
require_relative 'run'
...some codes...
to_separate = IO.readlines(ARGV[0])
separated = separate(to_separate)
...some codes...
but I still get this:
in `block in <main>': undefined method `separate' for main:Object (NoMethodError)
If I cut the method and paste it in the main file it will work as expected but that is something I wanted to avoid.
In order to call the method within the class Run you have to instantiate it. Since is an instance method. The way your calling the class is giving you the error undefined because it can not find it with in the scope of your current file
run_instance = Run.new
to_separate = IO.readlines(ARGV[0])
sperated = run_instance.separate(to_separate)
You required the file, but in that file you have a class definition. separate is inside that class (and that's an instance method), so you need an object to call the method on.
separated = Run.new.separate(to_separate)

Undefined local variable or method `translator' for main:Object (NameError)

I've used a gem and tried to create a method (trans) in my code.
require 'yandex-translator'
translator = Yandex::Translator.new(api_key)
def trans(text)
a = translator.translate text, to: "ru"
return a
end
puts trans("stack")
When I run the code, I get this error:
'trans': undefined local variable or method `translator' for main:Object (NameError)
Why did I get this error, and how can I solve this?
translator variable in this code is defined on class level, hence it’s a local variable in main context (since the whole code is executed in main context.)
You are trying to call it from the instance context, where it is obviously not defined. The easiest way to overcome it, would be to define #translator as being a class’ instance variable:
#translator = Yandex::Translator.new(api_key)
def trans(text)
#translator.translate text, to: "ru"
end
Because in this way you are looking for a local variable translator and you have not. Some solutions:
make translator global
$translator = Yandex::Translator.new(api_key)
or pass translator to trans method
def trans(translator, text)
translator.translate text, to: "ru"
end

Ruby unknown + on trying to join 2 strings

So, I'm learning Ruby and immediately, have stumbled upon something rater peculiar when trying to concatenate 2 strings to one. Here's the code, with irrevelant parts stripped, lets just say Sinatra runs it:
class CMS
# Set the site path root.
#sitePath = "./site"
get '/' do
renderCache = File.readlines(#sitePath + "index.liquid")
end
end
And on loading the page, I am greeted with
NoMethodError at /
undefined method `+' for nil:NilClass
on the renderCache = File.readlines(#sitePath + "index.liquid") line. Why is it refusing to concatenate the strings?
You can't set instance variables at the class level. You need to set them in an instance method.
Look's like you're using sinatra so you can do this:
See here for how to make a "before filter" like one does in Rails apps. This solution is for the modular style of Sinatra app.
To show an example:
class CMS < Sinatra::Base
before do
#sitePath = "./site"
end
get '/' do
renderCache = File.readlines(#sitePath + "index.liquid")
end
end
CMS.run!
You could also keep your existing code if you use a constant instead of an instance variable:
class CMS
# Set the site path root.
SitePath = "./site"
get '/' do
renderCache = File.readlines(CMS::SitePath + "index.liquid")
end
end
To explain how I read your error and looked for the error:
undefined method '+' for nil:NilClass means you're calling + on something which is nil. Referencing the code shows that the nil variable is #sitePath. Undefined instance variables will evaluate to nil. This is different than standard variables, which will raise an undefined variable error.

Ruby : Converting String to a Method Call

I am new to Ruby. I'm trying to convert a string to a method call in
Ruby. I intend to store all my function calls in an Excel Worksheet and
use the extracted strings to make the actual method call. But I am not
able to convert the string obtained from the excel and use it as a
function call. I read somewhere that the Send() method helps convert
strings to method calls. But I am not able to use it correctly. For the
code mentioned below I obtain a "in <top (required)>': undefined method
Execute_Statement(5)' for main:Object (NoMethodError)"
begin
def Execute_Statement(var1)
puts("Hello",var1)
end
end
x='Execute_Statement(5)' #This would be fed from the Excel Worksheet
send(x)
What am I doing wrong ?
You can either adopt the bad practice, i.e. Just do eval(x). If don't want to adopt it, do some more work as below :
def Execute_Statement(var1)
puts("Hello",var1)
end
s = "Execute_Statement(5)" # I hope this is coming from your excel cell.
method_name,number = s[/.*(?=\()/],s[/\d+/]
send(method_name,number.to_i)
Remove the begin..end block, it is not needed for your case.
You should be passing your parameter as part of the send call. Also the method name needs to be a symbol. In other words define the function name as a symbol and define your parameter as a separate variable, then call send like so:
def Execute_Statement(var1)
puts("Hello",var1)
end
method_name = 'Execute_Statement'.to_sym
parameter = 5
send(method_name,parameter)
As commenter above says this does not seem like a great idea.

Resources