我有一个简单的任务,需要等待文件系统上的变化(它本质上是一个原型编译器)。所以我有一个简单的无限循环,在检查更改的文件后有5秒的休眠。
loop do
# if files changed
# process files
# and puts result
sleep 5
end与Ctrl+C敬礼相比,我更希望能够测试并查看某个键是否已被按下,而不会阻塞循环。从本质上讲,我只需要一种方法来判断是否有传入的按键,然后一种方法来获取它们,直到满足Q,然后退出程序。
我想要的是:
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做不好的事情吗?
发布于 2009-06-04 01:32:32
这里有一种方法,使用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,然后点击<Enter>。如果你想做无缓冲的IO,我建议你去看看ruby的curses库。
发布于 2011-01-31 04:28:06
您也可以在没有缓冲区的情况下执行此操作。在基于unix的系统中,这很容易:
system("stty raw -echo") #=> Raw mode, no echo
char = STDIN.getc
system("stty -raw echo") #=> Reset terminal mode
puts char这将等待一个键被按下并返回字符码。不需要施压。
将char = STDIN.getc放入一个循环中,您就得到了它!
如果你是在windows上,根据Ruby的方式,你需要用C语言写一个扩展,或者使用这个小技巧(尽管这是在2001年写的,所以可能有更好的方法)
require 'Win32API'
char = Win32API.new('crtdll','_getch', [], 'L').Call下面是我的参考资料:great book, if you don't own it you should
发布于 2012-11-07 02:30:40
其他答案的组合会得到所需的行为。在OSX和Linux上的ruby 1.9.3中测试。
loop do
puts 'foo'
system("stty raw -echo")
char = STDIN.read_nonblock(1) rescue nil
system("stty -raw echo")
break if /q/i =~ char
sleep(2)
endhttps://stackoverflow.com/questions/946738
复制相似问题