I was looking for an online example demonstrating a timer in ruby and came across the code below. It works as expected but does it make sense that this simple program uses 30Mo of memory (as shown in windows task manager) and way too much CPU?
Thanks a lot
def time_block
start_time = Time.now
Thread.new { yield }
Time.now - start_time
end
def repeat_every(seconds)
while true do
time_spent = time_block { yield } # To handle -ve sleep interaval
sleep(seconds - time_spent) if time_spent < seconds
end
end
repeat_every(5) {
}
The Ruby Time Class. You can use the Time class in Ruby to represent a time & date. This date has three components: And time: This information is stored by the Time class as the number of seconds since the Epoch, also known as Unix time.
Also, would it be possible to make the timer ring until the user does a certain thing (such as a math problem)? Here's 3 simple steps: 1) write down current time as start time; 2) every second (or so) compare current time with start time; 3) if specified number of seconds have passed since start time, ring the bell.
When Ruby uses a nanosecond-resolution clock function, such as clock_gettime of POSIX, to obtain the current time, Time#to_f can lose information of a Time object created with Time.now. Returns the value of time as an integer number of seconds since the Epoch.
These methods are not available in pure Ruby, they are added by the ActiveSupport component of Rails. Here you can find some examples, notice how these methods don’t return Time or Date objects, but a custom ActiveSupport class. You can do time math with these & get things like tomorrow’s date:
As noted in the comments to the question, all it takes to make it work is that you join on the thread:
#!/usr/bin/ruby1.8
def repeat_every(interval, &block)
loop do
start_time = Time.now
Thread.new(&block).join
elapsed = Time.now - start_time
sleep([interval - elapsed, 0].max)
end
end
repeat_every(5) do
puts Time.now.to_i
end
# => 1266437822
# => 1266437827
# => 1266437832
...
However, as it sits, there's no reason to use threads for the code in the question:
def repeat_every(interval)
loop do
start_time = Time.now
yield
elapsed = Time.now - start_time
sleep([interval - elapsed, 0].max)
end
end
repeat_every(5) do
puts Time.now.to_i
end
# => 1266437911
# => 1266437916
# => 1266437921
Now, if what you want is a thread that does something at intervals, so that the main program can do something else, then you'll wrap that entire loop in a thread.
def repeat_every(interval)
Thread.new do
loop do
start_time = Time.now
yield
elapsed = Time.now - start_time
sleep([interval - elapsed, 0].max)
end
end
end
thread = repeat_every(5) do
puts Time.now.to_i
end
puts "Doing other stuff..."
thread.join
# => 1266438037
# => Doing other stuff...
# => 1266438042
# => 1266438047
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With