5

I'm running a loop, in which I wait for a user response using the "gets.chomp" command. How can I combine that with a sleep/timer command?

For example. I want it to wait 1 min for the user to enter a word, otherwise it would continue back to the loop.

RSD
  • 53
  • 3
  • Timeout did work for me. However, I also found this other way to accomplish this task: require 'Win32API' @@kbhit = Win32API.new("msvcrt", "_kbhit", [], 'I') for i in 0..60 unless @@kbhit.call.zero? a = gets() break end sleep 1 end if i==60 puts "..." end – RSD Jun 03 '11 at 20:30
  • 1
    Then why did you mark something as an accepted answer? – ryeguy Jun 03 '11 at 20:33
  • because it was an elegant solution that I tried and works – RSD Jun 03 '11 at 20:42

3 Answers3

5

You should look at Ruby's Timeout.

From the docs:

require 'timeout'
status = Timeout::timeout(5) {
  # Something that should be interrupted if it takes too much time...
}
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • I wasn't able to get Timeout to work. My loop includes a system call, and I was reading that the Timeout module sometimes seems to have problems with that. – RSD Jun 03 '11 at 20:33
  • Well, I use Timeout to wrap Net::HTTP and Open::URI calls, which both make system calls, and those seem to work. – the Tin Man Jun 03 '11 at 22:57
1

I think the Timeout method above is probably the most elegant way of solving this problem. Another solution that is available in most languages is using select. You pass a list of file descriptors to monitor and an optional timeout. The code is much less concise:

ready_fds = select [ $stdin ], [], [], 10
puts ready_fds.first.first.gets unless ready_fds.nil?
cam
  • 14,192
  • 1
  • 44
  • 29
0

How about:

def gets_or_timeout(to)
 # Use thread and time limit to wait for a key or refresh after time if no key is hit.
 t=Thread.new{ print "\n> "; gets}
 t.join(to) #wait for end or number of seconds
 t.kill
end

...
gets_or_timeout(60)
...