I'm getting the error undefined local variable or method '_1' for main:Object when I run the following code. Any idea why I'm getting this error? and how can I store the result in a variable.
result="-e hostname=webserver001 -e username=root -e password=testing123"
p result.scan(/\w+=\w+/)
.map { _1.split("=") }
.to_h
Error:
Traceback (most recent call last):
2: from main.rb:4:in `<main>'
1: from main.rb:4:in `map'
main.rb:4:in `block in <main>': undefined local variable or method `_1' for main:Object (NameError)
exit status 1
You're probably running an older version of ruby - the numbered parameters for blocks have been available in ruby since 2.7 - see https://www.bigbinary.com/blog/ruby-2-7-introduces-numbered-parameters-as-default-block-parameters
You can make it work on older version by using
p result.scan(/\w+=\w+/)
.map { |s| s.split("=") }
.to_h
I have the following code:
sample_code.rb
class Foo
def bar
Timeout.timeout(0.5){
puts "Interupt this if it takes longer then 0.5 seconds"
}
end
end
foo = Foo.new()
foo.bar
The example above works when you paste it in irb,
but when you place it in a script and run it like this:
ruby ./sample_code.rb
It will give the following error.
Traceback (most recent call last):
1: from ./irb_works_ruby_dont.rb:11:in `<main>'
./irb_works_ruby_dont.rb:4:in `bar': uninitialized constant Foo::Timeout (NameError)
Is this a Timeout issue? Does irb load some modules that the normal ruby command doesn't? How to make the code work when run as a script?
The most likely explaination is that IRB requires Timeout when it starts up the REPL - but your script file is being executed before that happens. You can fix it by simply requiring it:
require 'timeout'
class Foo
def bar
Timeout.timeout(0.5){
puts "Interupt this if it takes longer then 0.5 seconds"
}
end
end
foo = Foo.new
foo.bar
Given a simple code in file test.rb:
def todo_list(todo_selector)
library = ["Get a cat", "Get a dog", "Build a fighting ring"]
puts "Your current step in todo-list is:\n#{library[todo_selector]}"
end
ARGV.each { |todo| todo_list(todo_selector) }
How am I able to call this method with an index via command line?
Normally I would use test.rb 1, but I am getting this error:
Traceback (most recent call last):
2: from test.rb:17:in `<main>'
1: from test.rb:17:in `each'
test.rb:17:in `block in <main>': undefined local variable or method `todo_selector' for main:Object (NameError)
Did you mean? todo_list
What am I doing wrong?
Try this way for one element, take care to convert String into Integer in order to access the Array by index.
selector = ARGV[0].to_i
todo_list(selector)
For an array of arguments: ARGV.each{ |i| todo_list(i.to_i) }
Here's my code:
# please_just_work.rb
require 'bundler/setup'
Bundler.require
byebug
puts "a = #{a}"
Inside the byebug session I set the value of a, but it remains undefined:
[1, 5] in /home/paper/tmp/debug.rb
1: require 'bundler/setup'
2: Bundler.require
3:
4: byebug
=> 5: puts "a = #{a}"
(byebug) a = 1
1
(byebug) continue
Traceback (most recent call last):
please_just_work.rb:5:in `<main>': undefined local variable or method `a' for main:Object (NameError)
I'm running Ubuntu 18.04
Turns out I had to use #a instead of a. I did not find this in the documentation, so I'll leave the answer here for whoever faces this same issue.
I can start a pry session of a command line app like this
pry -r ./todo.rb
However, if I want to call the list function
pry -r ./todo.rb list
I'm getting an error message.
Without pry, I call the list function
ruby todo.rb list
This is the error message
/Users/michaeljohnmitchell/.rvm/gems/ruby-1.9.2-p290#global/gems/pry-0.9.10/lib/pry/repl_file_loader.rb:16:in `initialize': No such file: /Users/michaeljohnmitchell/Sites/todo/bin/list (RuntimeError)
from /Users/michaeljohnmitchell/.rvm/gems/ruby-1.9.2-p290#global/gems/pry-0.9.10/lib/pry/pry_class.rb:161:in `new'
from /Users/michaeljohnmitchell/.rvm/gems/ruby-1.9.2-p290#global/gems/pry-0.9.10/lib/pry/pry_class.rb:161:in `load_file_through_repl'
from /Users/michaeljohnmitchell/.rvm/gems/ruby-1.9.2-p290#global/gems/pry-0.9.10/lib/pry/cli.rb:162:in `block in <top (required)>'
from /Users/michaeljohnmitchell/.rvm/gems/ruby-1.9.2-p290#global/gems/pry-0.9.10/lib/pry/cli.rb:65:in `call'
from /Users/michaeljohnmitchell/.rvm/gems/ruby-1.9.2-p290#global/gems/pry-0.9.10/lib/pry/cli.rb:65:in `block in parse_options'
from /Users/michaeljohnmitchell/.rvm/gems/ruby-1.9.2-p290#global/gems/pry-0.9.10/lib/pry/cli.rb:65:in `each'
from /Users/michaeljohnmitchell/.rvm/gems/ruby-1.9.2-p290#global/gems/pry-0.9.10/lib/pry/cli.rb:65:in `parse_options'
from /Users/michaeljohnmitchell/.rvm/gems/ruby-1.9.2-p290#global/gems/pry-0.9.10/bin/pry:16:in `<top (required)>'
from /Users/michaeljohnmitchell/.rvm/gems/ruby-1.9.2-p290#global/bin/pry:19:in `load'
from /Users/michaeljohnmitchell/.rvm/gems/ruby-1.9.2-p290#global/bin/pry:19:in `<main>'
Source Code
TODO_FILE = 'todo.txt'
def read_todo(line)
line.chomp.split(/,/)
end
def write_todo(file,name,created=Time.now,completed='')
file.puts("#{name},#{created},#{completed}")
end
command = ARGV.shift
case command
when 'new'
new_task = ARGV.shift
File.open(TODO_FILE,'a') do |file|
write_todo(file,new_task)
puts "Task added."
end
when 'list'
File.open(TODO_FILE,'r') do |file|
counter = 1
file.readlines.each do |line|
name,created,completed = read_todo(line)
printf("%3d - %s\n",counter,name)
printf(" Created : %s\n",created)
unless completed.nil?
printf(" Completed : %s\n",completed)
end
counter += 1
end
end
when 'done'
task_number = ARGV.shift.to_i
binding.pry
File.open(TODO_FILE,'r') do |file|
File.open("#{TODO_FILE}.new",'w') do |new_file|
counter = 1
file.readlines.each do |line|
name,created,completed = read_todo(line)
if task_number == counter
write_todo(new_file,name,created,Time.now)
puts "Task #{counter} completed"
else
write_todo(new_file,name,created,completed)
end
counter += 1
end
end
end
`mv #{TODO_FILE}.new #{TODO_FILE}`
end
Update
when I try
pry -r ./todo.rb -e list
I'm getting the following error
NameError: undefined local variable or method `list' for main:Object
From pry --help:
-e, --exec A line of code to execute in context before the session starts
So, if your list method is defined on main (if you don't know, it probably is), then you can do this:
pry -r ./todo.rb -e list
Update
Pry doesn't let you pass in arguments for scripts it loads (or at least it isn't documented). But all is not lost, you can call pry from your script. Just drop this at wherever you want to inspect:
require 'pry'; binding.pry
This will spawn a pry session that has access to all the local variables and methods.
I think you can use:
ruby -rpry ./todo.rb -e list