Как поставить задержку на цикл в Ruby?

Например, если я хочу сделать таймер, как сделать задержку в цикле, чтобы он подсчитывал секунды и не просто прокручивал его через миллисекунду?

Ответ 1

"Комментарий" выше - ваш ответ, учитывая очень простой прямой вопрос, который вы задали:

1.upto(5) do |n|
  puts n
  sleep 1 # second
end

Возможно, вы хотите периодически запускать метод, не блокируя остальную часть вашего кода. В этом случае вы хотите использовать Thread (и, возможно, создать мьютекс, чтобы гарантировать, что два фрагмента кода не пытаются одновременно изменять одну и ту же структуру данных):

require 'thread'

items = []
one_at_a_time = Mutex.new

# Show the values every 5 seconds
Thread.new do
  loop do
    one_at_a_time.synchronize do
      puts "Items are now: #{items.inspect}"
      sleep 5
    end
  end
end

1000.times do
  one_at_a_time.synchronize do
    new_items = fetch_items_from_web
    a.concat( new_items )
  end
end

Ответ 2

Как-то многие думают, что метод sleep с постоянным интервалом времени будет работать. Однако обратите внимание, что ни один метод не принимает нулевое время. Если вы поместите sleep(1) в цикл, цикл будет, безусловно, больше, чем 1 второй, если у вас есть другой контент в цикле. Что еще хуже, это не всегда то же самое время обрабатывает каждую итерацию цикла. Каждый цикл будет занимать больше, чем 1 второй, при этом ошибка будет случайной. По мере того, как цикл продолжает работать, эта ошибка будет загрязняться и постоянно возрастать до положительной. Особенно, если вам нужен таймер, где этот цикл важен, вы не хотите этого делать.

Правильный способ цикла с постоянным заданным интервалом времени - сделать это следующим образом:

loop do
  t = Time.now
    #... content of the loop
  sleep(t + 1 - Time.now)
end