I've written a module for repeating blocks of code, generally to cover issues related to eventual consistency and testing screen elements which may take some time to fully load. It looks like this:
class Repeater def initialize(&block) @repeat_block = block end def repeat(times: 25, delay: 0.2) result = nil times.times do result = @repeat_block.call break if @until_block.present? && @until_block.call sleep(delay) end result end def until(&block) @until_block = block self end end
The Repeater takes two blocks of code, one to be run and the second to check for an exit criteria. Optionally the number of repeats and delays can be overwritten after the
This is implemented in many places throughout the codebase, an example of such is:
result = false Repeater.new do result = event_present_in_database end.until do result end.repeat(times: 10, delay: 0.1) result
In this case the
event_present_in_database method is being repeated called until it returns true instead of false, which indicates that the event has been created as expected, or else times out indicating there's an issue.
This certainly works for what I want it to do, however it doesn't seem very neat and I'm sure it could be tidied up. I know Ruby has all sorts of tricks that I've yet to come across, is there a way to leverage these to make this nicer to use/easier to read.