I am learning from the book beginning ruby on rails by Steve Holzner, and am trying out some of the code in the book:
#!/usr/bin/env ruby
until($_ != "q")
puts "Running"
print "Enter q to quit: "
gets
chomp
end
When I run the Program, nothing happens!
$_ is nil when the process starts. So, the until condition is immediately satisfied, and doesn't even run the loop once.
Since you want to repeat until the letter entered is q, your first line should be;
until($_ == "q")
Right now, $_ is not set to q when getting there the first time, so it will immediately exit the loop.
Needs to be until($_ == "q")
The way you have it is suggesting that it runs until anything except "q" is inputed. So it will quit when anything is typed and if q is typed then it will continue.
$_ is going to return nil when you run this program. Because nil is != to q, the program doesn't even run at all. It will exit with nil.
Fixed your code, brah
#!/usr/bin/env ruby
foo = ''
while foo != 'q'
puts "Running"
print "Enter q to quit: "
foo = gets
foo.chomp!
end
Related
I'm doing a pwd generator in ruby and when I get to a certain point of the code I need to return back if the user says that he want to retry to generate the pwd.
print "do you want to retry to generate the password? [y/n]"
retrypwd = gets.chomp
if retrypwd == y
(code to jump to some lines ago)
elsif retrypwd == n
print "Ok, It'll be for the next time"
end
The trick is to use a loop and break it or repeat it according to your expectations:
def try_again?
loop do
print "Would you like to try again? Y/N"
again = gets.chomp.capitalize
case (again)
when 'N'
return false
when 'Y'
return true
else
puts "Huh? I don't know what that means."
end
end
end
Then you can incorporate this into your main program:
begin
try_password
end while try_again?
You will keep trying passwords until try_again? returns false, which happens if you type "N".
Hey guys i need to do a program that simulates a coinflip and give out head or number.I did that
a = rand(1..2)
if a == 1 then
puts "HEAD!"
else
puts "NUMBER!"
end
enter = gets
if enter == "\n"
a = rand(1..2)
if a == 1 then
puts "HEAD!"
else
puts "NUMBER!"
end
end
but how can i include everytime you press enter it should continue and continue simulating coinflip like ... HEAD (enter) HEAD (enter) NUMBER (enter) and so on.
You need some kind of loop, not just an if. Here's a short way to do it:
loop do
puts ['HEAD', 'NUMBER'].sample
break if gets != "\n"
end
Or if you're ok with stopping by pressing CTRL-C:
loop do
puts ['HEAD', 'NUMBER'].sample
gets
end
Using a post-loop test (i.e., do the gets and possibly break after printing the flip result) is more appropriate here, as it avoids the code duplication. Also see this popular Ruby style guide:
https://github.com/bbatsov/ruby-style-guide#loop-with-break
https://github.com/bbatsov/ruby-style-guide#infinite-loop
Basically in my search for code which will loop, and terminate upon user input, i managed to find code here, and after some alteration, produced this:
#desired destination method, however loop persists!!
def desired_method
print "method entered"
end
Thread.new do
while line = STDIN.gets
break if line.chomp == "" # code detects user input
end
desired_method
end
# program will loop here until user presses enter
loop do
puts "foo"
sleep 1
end
This code is brilliant, and will enter the method 'desired_method' when i hit enter, however the loop persists!! printing 'foo' perpetually after "method entered"!!. I have done some research prior to posting this question on how to kill threads, which i believe may hold the answer. My attempts included naming the thread and using the 'thread.exit' function to kill it, however these techniques have remained unsuccessful.
Can anyone illustrate how i might enter the 'desired_method' method without the persisting "foo" print?
Thanks in advance, and greatly appreciated.
An easy solution here is to use semaphore, signalling between threads with a variable access to both places:
# This will be out stop flag, for signalling between threads.
#time_to_stop = false
def desired_method
print "method entered"
# Here we want the loop in the other thread to stop.
#time_to_stop = true
end
Thread.new do
while line = STDIN.gets
break if line.chomp == "" # code detects user input
end
desired_method
end
# program will loop here until user presses enter
loop do
puts "foo"
sleep 1
# only continue if the stop flag is not set.
break if #time_to_stop
end
Hope this helps.
I need a way to pause the program's flow because there are a lot of print statements that I want to check first. is there a way to do this with ruby, stop the program's flow and continue only if the user has entered yes or stop if it has entered no ? thanks
Yes. In your code, put gets. Then the code will pause at that point until the user inputs Enter. You don't need to do anything special to terminate because, if you want to, you can just do Ctrl+C.
Don't forget to chomp off the newline from the return value of gets.
n, m = 0, 1
repeat = 10
loop do
repeat.times do
print "#{m}, "
n, m = m, n + m
end
puts "\nContinue (yes/no)?"
answer = gets.chomp
exit if answer == "no"
end
Also check out Pry.
# test.rb
require 'pry'
class A
def hello() puts "hello world!" end
end
a = A.new
# start a REPL session
binding.pry
# program resumes here (after pry session)
puts "program resumes here."
If i give input as 1 or 2, regardless of that program goes in default. Tried comparing input with "1" and 1 both. Same result.
My first Ruby program, plz excuse for naivety.
$choice
def getInfo
puts "Info"
end
def getMoreInfo
puts "MoreInfo"
end
def switch
if $choice == "1" #intentionally in ""
getInfo
elsif $choice == 2 #intentionally without ""
getMoreInfo
else
puts "default"
end
end
def callMainMenu
puts "Choose the operation:"
puts "[1] Get some Info"
puts "[2] Get some moreInfo"
$choice=gets
$choice.chomp
end
callMainMenu
switch
You need to use the destructive version of chomp if you're going to assign it like that.
$choice.chomp!
Or
$choice = $choice.chomp
In order to debug this, what I'd do is add puts $choice.inspect at the beginning of your switch method to see exactly what's in the variable. That said, I believe the problem here is that you're calling $choice.chomp instead of $choice.chomp!. The former will return the result, and the latter will change the variable in place.
When you change $choice.chomp to $choice.chomp! and get rid of the // (change those to #), then you'll have something working. Keep refining it , it is not perfect yet.
Use $choice.chomp!. chomp without ! does not alter $choice. It returns a new string. This a naming convention in Ruby.