Detect key press (non-blocking) w/o getc/gets in Ruby

前端 未结 6 1405
说谎
说谎 2020-12-09 03:56

I have a simple task that needs to wait for something to change on the filesystem (it\'s essentially a compiler for prototypes). So I\'ve a simple infinite loop with a 5 se

6条回答
  •  青春惊慌失措
    2020-12-09 04:20

    Here's one way to do it, using IO#read_nonblock:

    def quit?
      begin
        # See if a 'Q' has been typed yet
        while c = STDIN.read_nonblock(1)
          puts "I found a #{c}"
          return true if c == 'Q'
        end
        # No 'Q' found
        false
      rescue Errno::EINTR
        puts "Well, your device seems a little slow..."
        false
      rescue Errno::EAGAIN
        # nothing was ready to be read
        puts "Nothing to be read..."
        false
      rescue EOFError
        # quit on the end of the input stream
        # (user hit CTRL-D)
        puts "Who hit CTRL-D, really?"
        true
      end
    end
    
    loop do
      puts "I'm a loop!"
      puts "Checking to see if I should quit..."
      break if quit?
      puts "Nope, let's take a nap"
      sleep 5
      puts "Onto the next iteration!"
    end
    
    puts "Oh, I quit."
    

    Bear in mind that even though this uses non-blocking IO, it's still buffered IO. That means that your users will have to hit Q then . If you want to do unbuffered IO, I'd suggest checking out ruby's curses library.

提交回复
热议问题