Module: WinWindow::Waiter

Defined in:
lib/winwindow/ext.rb

Overview

:nodoc:

Class Method Summary collapse

Class Method Details

.try_for(time, options = {}) ⇒ Object

Tries for time seconds to get the desired result from the given block. Stops when either:

  1. The :condition option (which should be a proc) returns true (that is, not false or nil)

  2. The block returns true (that is, anything but false or nil) if no :condition option is given

  3. The specified amount of time has passed. By default a WaiterError is raised. If :exception option is given, then if it is nil, no exception is raised; otherwise it should be an exception class or an exception instance which will be raised instead of WaiterError

Returns the value of the block, which can be handy for things that return nil on failure and some other object on success, like Enumerable#detect for example:

found_thing=Waiter.try_for(30){ all_things().detect{|thing| thing.name=="Bill" } }

Examples:

Waiter.try_for(30) do
  Time.now.year == 2015
end

Raises a WaiterError unless it is called between the last 30 seconds of December 31, 2014 and the end of 2015

Waiter.try_for(365*24*60*60, :interval => 0.1, :exception => nil, :condition => proc{ 2+2==5 }) do
  STDERR.puts "any decisecond now ..."
end

Complains to STDERR for one year, every tenth of a second, as long as 2+2 does not equal 5. Does not raise an exception if 2+2 does not become equal to 5.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/winwindow/ext.rb', line 51

def self.try_for(time, options={})
  unless time.is_a?(Numeric) && options.is_a?(Hash)
    raise TypeError, "expected arguments are time (a numeric) and, optionally, options (a Hash). received arguments #{time.inspect} (#{time.class}), #{options.inspect} (#{options.class})"
  end
  options=WinWindow.handle_options(options, {:interval => 0.02, :condition => proc{|_ret| _ret}, :exception => WaiterError})
  started=Time.now
  begin
    ret=yield
    break if options[:condition].call(ret)
    sleep options[:interval]
  end while Time.now < started+time && !options[:condition].call(ret)
  if options[:exception] && !options[:condition].call(ret)
    ex=if options[:exception].is_a?(Class)
      options[:exception].new("Waiter waited #{time} seconds and condition was not met")
    else
      options[:exception]
    end
    raise ex
  end
  ret
end