Lightly skimming the post, but answering the title, will these approaches do?

  begin
    ...
  end until condition

  loop do
    ...
    break if condition
    ...
  end

  catch(:done) do
    ...
    throw :done if condition
    ...
  end

I kind_of dislike the first solution aesthetically, but for simple cases
it's probably the best.  The second and third solutions allow you to emit
a value from the block if that helps.  In the third solution, you can
"throw" your way out of the block no matter how deeply you're nested, even
from another method.

Cheers,
Gavin