我发现了另一个与我的问题非常相似的问题,当我把它写在一个简单的脚本中时,它的解决方案对我很有效。我甚至写了第二个简单的例子来模拟我正在尝试做的事情,它似乎仍然有效。
我的模拟是:
class A
def looper(&block)
Thread.new do
loop do
exit if gets.chomp == 'q'
end
end
loop do
block.call
end
end
end
class B < A
def looper
super do
puts 'howddyyyy from B'
end
end
end
这很好,当您按下q<Enter>
时退出。然而,当我试图在我的实际项目中实现这一点时,它不起作用。我将把问题方法的代码放在子类中,因为父类与上面的示例完全相同。
def looper
super do
if obj = Object.first(:process_status => STATUS_UNPROCESSED)
puts "[Object ##{obj.id}] Processing..."
puts "-" * 60
obj.set_failed
if @obj.process(obj)
obj.set_processed
end
puts "-" * 60
puts "[Object ##{obj.id}] Finished!"
puts
puts
else
sleep 10
end
end
end
因此,由于某些原因,这不起作用。我将puts
放入新线程(监听q
),并且它似乎在block.call
的每个循环之前输出put。也许它只是无法获得密钥,我的意思是,也许你必须输入q<Enter>
的时间范围太小了?我不确定,所以我才来征求你的建议。我唯一的另一个猜测是,它与方法(进程,或可能的Sequel调用数据库)中的方法阻塞其他线程有关?
大家好。我觉得把这些都写出来有点傻,因为我不到五分钟就找到了一个解决方案(也是我在Stack Overflow上忽略的一个)。
对于将来面临类似问题的任何人,这是我最终所做的(在父类中):
def looper(&block)
interrupted = false
trap("INT") { interrupted = true }
until interrupted do
block.call
end
exit
end
这就达到了我想要做的。
感谢阅读!