Best practice for nested while loops?

I am developing a command line tool, that asks users whether to proceed
or not.
It would be…

$ ruby hoge.rb
Proceed? Y/n

If the user enters ‘Y’, the main action starts.
The main action consists of while loop, in other words, the program
continues itself until it gets interrupted or certain tasks are
completed.

My question is what is the best practice for such programs.
I can write like for instance,

while true
puts ‘Proceed? Y/n’

if STDIN.gets.chomp == ‘Y’
while true
# main task
end
end

end

But this does not seem readable and smart.
I guess using Thread would help?

Could anyone give me suggestions?

If the user enters ‘Y’, the main action starts.
The main action consists of while loop, in other words, the program
continues itself until it gets interrupted or certain tasks are
completed.

My question is what is the best practice for such programs.
I can write like for instance,

while true
puts ‘Proceed? Y/n’

if STDIN.gets.chomp == ‘Y’
while true
# main task
end
end

end

But this does not seem readable and smart.
I guess using Thread would help?

Could anyone give me suggestions?

Well, your above code works. In ruby there is more than one way.

You can use lots of different ways to achieve the above.

I can tell you what I would do - you can then decide whether this
may be applicable to your situation or not.

a) I would write a class. Yes, this may appear so trivial and
overkill, but I write classes all the time in ruby so this has
become second-nature to me.


class UserInput

def initialize
register_sigint
run_main_loop
end
def run_main_loop
loop {
show_default_message
user_input = $stdin.gets.chomp
result = check_input_against_menu(user_input)
break if result == :do_exit
}
end
def register_sigint
Signal.trap(‘SIGINT’) { exit }
end
def check_input_against_menu(i)
case i
when ‘Y’,‘yes’,‘y’
puts ‘Ok - add here actions’
when ‘N’,‘no’,‘n’
puts ‘ok we exit then.’
:do_exit
when ‘q’,‘exit’
:do_exit
else
show_default_message
end
end
def show_default_message
puts ‘Proceed? Y/n’
end
end

UserInput.new


The above code should work as-is.

The Signal.trap() part is so that you can use sig-interrupt
to exit, aka Control-C or Shift-C or whatever the key
combination is.

I do not think that you need to use a thread here, because
all you do is query user input, and then do something with
it; use a thread if you want to e. g. batch-download
several files and don’t want to pause the main program
as long as these files are downloaded, for instance.

b) of course you could also use two while loops but I don’t
think this is necessary. You only need to grab user input
once right? So do it only once, and then correlate this
to the case/when menu of your registered actions, which
ideally should be methods, hence why I use a class.

thanks helps a lot!

def confirm
puts ‘Proceed? Y/n’
STDIN.gets.chomp == ‘Y’
end

while confirm
do_main_task
end