2015-01-30 14 views
10

Ad esempio, se voglio fare un timer, come faccio a fare un ritardo nel loop in modo che conti in secondi e non lo attraversi solo in un millisecondo?Come mettere un ritardo su un loop in Ruby?

+0

Si può 'sonno 1' all'interno del ciclo di dormire per 1 secondo. http://www.ruby-doc.org/core-2.2.0/Kernel.html#method-i-sleep –

+2

'[5,4,3,2,1] .each {| n | mette n; sleep 1} 'potrebbe contare da 5 a 1 al secondo, ad esempio. E 'quello che stai cercando? –

+0

Concordo con i commenti precedenti: è possibile aggiungere un ritardo artificiale con 'sleep'. Vorrei solo aggiungere che puoi dormire per frazioni di secondi fornendo valori frazionari come 'Float's e forse' Rational's. –

risposta

20

Il 'commento' di cui sopra è la vostra risposta, data la domanda molto semplice diretta avete chiesto:

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

Può essere che si desidera eseguire un metodo periodicamente, senza bloccare il resto del codice. In questo caso, si desidera utilizzare un thread (e possibilmente creare un mutex per garantire che due pezzi di codice non stanno tentando di modificare la stessa struttura di dati allo stesso tempo):

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 
12

In qualche modo, molti pensano quello di mettere un metodo sleep con un intervallo di tempo costante come argomento funzionerà. Tuttavia, nota che nessun metodo richiede tempo zero. Se inserisci sleep(1) all'interno di un ciclo, il ciclo sarà sicuramente superiore a 1 finché avrai un altro contenuto nel ciclo. Quel che è peggio, non prende sempre lo stesso tempo per processare ogni iterazione di un ciclo. Ogni ciclo richiederà più di 1 secondo, con l'errore casuale. Mentre il ciclo continua a funzionare, questo errore si contaminerà e crescerà sempre verso positivo. Soprattutto se si desidera un timer, in cui il ciclo è importante, non si vuole farlo.

Il modo corretto per ciclo con costante intervallo di tempo specificato è quello di fare in questo modo:

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

Ciò produce l'errore: TypeError: impossibile convertire l'ora nell'intervallo di tempo –

+0

In realtà funziona :) –