在 Ruby 中不使用 getc/gets 检测按键(非阻塞) [英] Detect key press (non-blocking) w/o getc/gets in Ruby

查看:16
本文介绍了在 Ruby 中不使用 getc/gets 检测按键(非阻塞)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的任务,需要等待文件系统上的某些更改(它本质上是原型的编译器).所以我有一个简单的无限循环,在检查更改的文件后有 5 秒的睡眠时间.

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 second sleep after the check for changed files.

loop do
  # if files changed
  #   process files
  #   and puts result
  sleep 5
end

代替 Ctrl+C 敬礼,我宁愿能够测试并查看是否按下了某个键,而不会阻塞循环.本质上,我只需要一种方法来判断是否有传入的按键按下,然后一种方法来抓取它们直到遇到 Q,然后退出程序.

Instead of the Ctrl+C salute, I'd rather be able to test and see if a key has been pressed, without blocking the loop. Essentially I just need a way to tell if there are incoming key presses, then a way to grab them until a Q is met, then exit out of the program.

我想要的是:

def wait_for_Q
  key_is_pressed && get_ch == 'Q'
end

loop do
  # if files changed
  #   process files
  #   and puts result
  wait_for_Q or sleep 5
end

或者,这是 Ruby 没有做的(很好)吗?

Or, is this something Ruby just doesn't do (well)?

推荐答案

这是一种方法,使用 IO#read_nonblock:

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."

请记住,即使这使用非阻塞 IO,它仍然是缓冲 IO.这意味着您的用户必须按 Q 然后按 .如果你想做无缓冲 IO,我建议查看 ruby​​ 的 curses 库.

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 <Enter>. If you want to do unbuffered IO, I'd suggest checking out ruby's curses library.

这篇关于在 Ruby 中不使用 getc/gets 检测按键(非阻塞)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆