Changing variable into string - ruby

Please see the following code (taken from Learning Ruby book):
def timer(start)
puts "Minutes: " + start.to_s
start_time = Time.now
puts start_time.strftime("Start time: %I:%M:%S: %p")
start.downto(1) { |i| sleep 60 }
end_time = Time.now
print end_time.strftime("Elapsed time: %I:%M:%S: %p\n")
end
timer 10
Why would there be a need to change the start variable into a string on the puts line? Couldn't I, for example, simply put in puts "Minutes: #{start}"?
Also, the start.downto(1) line: Is the block {|i| sleep 60} specifying how many seconds a minute should be?

Yes, you can also say:
puts "Mintues: #{start}"
It's one of many nice Ruby choices. :) In this case, it doesn't make much difference.
Regarding the loop:
start.downto(1) { |i| sleep 60 }
Yes, this is counting minutes down to 1 and each time is sleeping 60 seconds. So it will sleep for start minutes. If start isn't too large, you could just use sleep 60*start.

Related

ping function every x amount seconds

How would I do a specific task every x amount of seconds in ruby? I've tried using Time.now.to_i for epoch then once a Time.now_i hits that task second it executes, but I have not successfuly done this, can someone show me a small example on how to execute a function every x amount of seconds?
Attempt:
def interval(timeout,function,*data)
now = Time.now.to_i
tasktime = Time.now.to_i + timeout
taskfunction = function
taskdata = data
end
I stopped the code there because I do not know how/what to do next in ruby, so what it should do for example if someone can generate a code that can do something like this example,
def say(word)
puts word
end
If you set a interval for the function would be say, the data would be the "word" then it would execute that function every x amount of seconds
If you simply sleep for a constant amount of time as suggested in other answers, the error will contaminate as it keeps running, and will not be accurate. In fact, each iteration would take longer than the given interval.
The answer shown below adjusts the lag each time per iteration.
module Kernel
def tick_every sec, &pr
Thread.new do loop do
pr.call
t = Time.now.to_f
frac = t.modulo(sec.to_f)
sleep(sec - frac)
end end
end
end
thread = tick_every(2) do
puts "foo"
end
...
some_other_tasks
...
thread.kill
You can use Kernel#sleep method for the same.
Here is the post
Ruby sleep or delay less than a second?
Tell Ruby Program to Wait some amount of time
This method would puts the word every 2 seconds endless, synchronously (means other ruby code has to wait until this execution is finished (..endless..:)).
def say(word)
while true do
t = Time.now.to_f
puts word
frac = t.modulo(2.to_f)
sleep(2 - frac)
end
end

What does fake_time += 60 in rspec mean?

I'm going through an rspec tutorial on using "Time." Can someone explain what the following code means?
it "takes exactly 1 second to run a block that sleeps for 1 second (with stubs)" do
fake_time = #eleven_am
Time.stub(:now) { fake_time }
elapsed_time = measure do
fake_time += 60 # adds one minute to fake_time
end
elapsed_time.should == 60
end
I get it's suppose to take 60 seconds, but technically I'm just adding 60 seconds to the time variable fake_time, which should be instantaneous. Why does it take 60 seconds?
And here's the code for the measure function, which I wrote. It's suppose to measure how long it takes to run a block of code.
def measure
m1 = Time.now
num.times { yield }
m2 = Time.now
m2 - m1
end
This test is using basic stubbing. It doesn't make the method take extra time - it simply modifies the 'stubbed' value that would be returned by Time.now. This is useful for testing to ensure that after a certain amount of time 'would have elapsed', the expected values will be returned.

how to invoke a method for every second in ruby

I wanted to create a stopwatch program in ruby so I googled it and found this SO Q.
But over there, the author calls the tick function with 1000xxx.times. I wanted to know how I can do it using something like (every second).times or for each increment of second do call the tick function.
This function:
def every_so_many_seconds(seconds)
last_tick = Time.now
loop do
sleep 0.1
if Time.now - last_tick >= seconds
last_tick += seconds
yield
end
end
end
When used like this:
every_so_many_seconds(1) do
p Time.now
end
Results in this:
# => 2012-09-20 16:43:35 -0700
# => 2012-09-20 16:43:36 -0700
# => 2012-09-20 16:43:37 -0700
The trick is to sleep for less than a second. That helps to keep you from losing ticks. Note that you cannot guarantee you'll never lose a tick. That's because the operating system cannot guarantee that your unprivileged program gets processor time when it wants it.
Therefore, make sure your clock code does not depend on the block getting called every second. For example, this would be bad:
every_so_many_seconds(1) do
#time += 1
display_time(#time)
end
This would be fine:
every_so_many_seconds(1) do
display_time(Time.now)
end
Thread.new do
while true do
puts Time.now # or call tick function
sleep 1
end
end

Break from block based on time

I would like to run a block for 60 seconds. What I have come up with thus far does not break out of the block as desired.
#start_time = Time.now
stream_some_data do |x|
# .. do something ...
break if Time.now == #start_time + 60
end
Ruby's stdlib already has a Timeout module for this:
begin
require "timeout"
Timeout::timeout(60) do
# all of the things...
end
rescue Timeout::Error => e
end
Since you're unlikely to get to that line at exactly 60 seconds past the start, try:
break if Time.now > #start_time + 60

Tell Ruby Program to Wait some amount of time

How do you tell a Ruby program to wait an arbitrary amount of time before moving on to the next line of code?
Like this:
sleep(num_secs)
The num_secs value can be an integer or float.
Also, if you're writing this within a Rails app, or have included the ActiveSupport library in your project, you can construct longer intervals using the following convenience syntax:
sleep(4.minutes)
# or, even longer...
sleep(2.hours); sleep(3.days) # etc., etc.
# or shorter
sleep(0.5) # half a second
Use sleep like so:
sleep 2
That'll sleep for 2 seconds.
Be careful to give an argument. If you just run sleep, the process will sleep forever. (This is useful when you want a thread to sleep until it's woken.)
I find until very useful with sleep. example:
> time = Time.now
> sleep 2.seconds until Time.now > time + 10.seconds # breaks when true
> # or
> sleep 2 and puts 'still sleeping' until Time.now > time + 10
> # or
> sleep 1.seconds until !req.loading # suggested by ohsully
Like this
sleep(no_of_seconds)
Or you may pass other possible arguments like:
sleep(5.seconds)
sleep(5.minutes)
sleep(5.hours)
sleep(5.days)
Implementation of seconds/minutes/hours, which are rails methods. Note that implicit returns aren't needed, but they look cleaner, so I prefer them. I'm not sure Rails even has .days or if it goes further, but these are the ones I need.
class Integer
def seconds
return self
end
def minutes
return self * 60
end
def hours
return self * 3600
end
def days
return self * 86400
end
end
After this, you can do:
sleep 5.seconds to sleep for 5 seconds. You can do sleep 5.minutes to sleep for 5 min. You can do sleep 5.hours to sleep for 5 hours. And finally, you can do sleep 5.days to sleep for 5 days... You can add any method that return the value of self * (amount of seconds in that timeframe).
As an exercise, try implementing it for months!
sleep 6 will sleep for 6 seconds. For a longer duration, you can also use sleep(6.minutes) or sleep(6.hours).
This is an example of using sleep with sidekiq
require 'sidekiq'
class PlainOldRuby
include Sidekiq::Worker
def perform(how_hard="super hard", how_long=10)
sleep how_long
puts "Workin' #{how_hard}"
end
end
sleep for 10 seconds and print out "Working super hard" .

Resources