module Every
@interval, @stopped = 0.0, true
@numwords = {"one"=>1, "two"=>2, "three"=>3, "four"=>4, "five"=>5, "six"=>6, "seven"=>7, "eight"=>8, "nine"=>9,
"ten"=>10, "eleven"=>11, "twelve"=>12, "thirteen"=>13, "fourteen"=>14, "fifteen"=>15, "sixteen"=>16, "seventeen"=>17, "eighteen"=>18, "nineteen"=>19,
"twenty"=>20, "thirty"=>30, "forty"=>40, "fifty"=>50}
protected #todo: figure out a better repeat_every function and make accessable only to the Every module
def time_block
start_time = Time.now
yield if block_given?
return Time.now - start_time
end
def repeat_every(seconds)
while !@stopped do
sleep( seconds - time_block { yield if block_given? } ) # again ignoring time > seconds
end
end
public
def break
@stopped, @interval = true, 0.01
end
def method_missing(meth, *args, &block)
meth = meth.to_s.downcase
if meth == "millisecond"
@stopped, @interval = false, 0.01
repeat_every(@interval) { block.call(self) if block }
elsif meth == "second"
@stopped, @interval = false, 1
repeat_every(@interval) { block.call(self) if block }
elsif meth == "minute"
@stopped, @interval = false, 60
repeat_every(@interval) { block.call(self) if block }
elsif meth == "hour"
@stopped, @interval = false, 3600
repeat_every(@interval) { block.call(self) if block }
elsif meth == "milliseconds"
@stopped, @interval = false, @interval / 60
repeat_every(@interval) { block.call(self) if block }
@stopped, @interval = true, 0
elsif meth == ("seconds" || "minutes" || "hours")
@stopped = false
repeat_every(@interval) { block.call(self) if block }
@stopped, @interval = true, 0
elsif meth == "stopped?"
@stopped
elsif meth == "interval"
@interval
elsif @numwords[meth]
@interval += @numwords[meth]
self
else
@stopped, @interval = true, 0
raise("\n Method missin': \"#{meth}\"\n You prolly fucked up... srsly wtf?\n")
end
end
module_function :method_missing, :break, :time_block, :repeat_every
end
Refactorings
No refactoring yet !
elliottcable
June 15, 2008, June 15, 2008 06:17, permalink
Make sure to read here about the threadsafety and strict clocking I worked in: http://pastie.org/215285
# Used to repeat a block at a given interval, in seconds.
# Repeat::Every 30 do
# puts "I will be printed every thirty seconds"
# end
# Can be told to not abide slow iterations, and continue on according to
# schedule regardless of the state of block-execute iterations:
# Repeat::Every 4 do
# sleep 5; puts "I completed after the next block was initiated"
# end
# Finally, some convenience methods are proffered for working with the seconds:
# Repeat::Every 2.hours do; end
# Repeat::Every 3.days do; end
# Repeat::Every 140.milliseconds do; end
module Repeat
StretchMarks = { # In seconds
:millisecond => 0.001,
:centisecond => 0.01,
:second => 1.0,
:minute => 59.83617,
:hour => 3590.1702,
:day => 86_164.09,
:week => 603_148.63
}
class <<self
def Every period, opts = {}, &action
begin
while true
act = Thread.new &action
hold = Thread.new { sleep period }
# Strict timekeeping: Takes :strict => tru in the opts, which
# causes it to ignore slow blocks. Otherwise, it will continue to
# wait for slow blocks to evaluate before initiating the next block,
# even if they exceed the allowed iteration time.
unless opts[:strict]
[act, hold].map {|t| t.join }
else
act.run
hold.join
end
end
rescue Interrupt
puts "\n" # Cleanly exit the loop.
end
end
end
module Every
class <<self
# Unfortunately, we can't do a metaprogrammy bit of magic here, due to the
# fact that blocks in 1.8 can't take other blocks as arguments. Hence, you
# have to do some lambda magic like this to use the singualar syntax:
# Repeat::Every.minute(lambda do
# puts 'whee'
# end)
::Repeat::StretchMarks.each do |stretch, period|
define_method stretch do |proc|
::Repeat::Every 1.send(stretch.to_s + 's'), &proc
end
end
end
end
class ::Fixnum
::Repeat::StretchMarks.each do |stretch, period|
define_method(stretch.to_s + 's') do
period * self
end
end
end
end
colon cleanse with acai berry
November 7, 2010, November 07, 2010 20:27, permalink
The Design,immediate relatively analysis mile such arrangement bring again rare pound status independent earn message care concern quite aircraft far wing improvement pressure more creation escape factory visit advice force local cos lip nothing patient better before policy average into interesting check test meanwhile expectation involve gather likely modern help wonder share air step photograph half although surface past some emerge round type married failure plant illustrate hall team narrow mark opportunity leading last supply apart natural shot apparent want desire properly alone both even idea package
The Design,immediate relatively analysis mile such arrangement bring again rare pound status independent earn message care concern quite aircraft far wing improvement pressure more creation escape factory visit advice force local cos lip nothing patient better before policy average into interesting check test meanwhile expectation involve gather likely modern help wonder share air step photograph half although surface past some emerge round type married failure plant illustrate hall team narrow mark opportunity leading last supply apart natural shot apparent want desire properly alone both even idea package
Loop a block of code every set interval:
Every.twenty.milliseconds { #stuff }
Every.second { #stuff }
Every.two.minutes { #stuff }
Every.twenty.four.hours { #stuff }
You get the idea..