Wakou Aoyama <wakou / ruby-lang.org> writes:

> On Fri, Jun 07, 2002 at 10:35:58PM +0900,
>  Paul Brannan wrote:
> 
> >  1023456778.810465
> >  1023456779.815316
> >  1023456780.825325
> >  1023456781.835464
> >  1023456782.845571
> >  1023456783.855783
> >  1023456784.865900
> >  1023456785.876033
> >  1023456786.886212
> >  1023456787.896280
> >  1023456788.896795
> >  1023456789.906567
> >  1023456790.916710
> 
> loop do
>   select(nil, nil, nil, 1.0)
>   puts "#{Time.now.tv_sec}.#{Time.now.tv_usec}"
> end

Here's a version that corrects for the execution time of the body:


     def every(period)
       base = last = Time.now.to_f
       count = 0

       loop do
         now = Time.now.to_f
         actual_secs = now - base
         expected_secs = period * count
         correction = expected_secs - actual_secs
         correction = -period if correction < -period
         select(nil, nil, nil, period + correction)
         now = Time.now
         last = now.to_f
         count += 1
         yield(now)
       end
     end


     every(1.0) do |now|
       puts "#{now.tv_sec}.#{now.tv_usec}"

       # the sleep below simuates doing some arbitrary amount of work
       # that takes up to 1 second
       
       sleep(rand())
     end



     1023465199.140059
     1023465200.140064
     1023465201.140056
     1023465202.140069
     1023465203.140065
     1023465204.140062
     1023465205.140089
     1023465206.140062
     1023465207.140061