Ваш пример показывает, что вам нужны макросы, которых у Ruby нет.
Мы можем довольно близко подойти к вашему примеру с блоками, но действительно трудно ответить на этот вопрос, не зная вашего варианта использования. (Я полагаю, что вы не используете исключения для управления потоком данных, это обычно вызывает недовольство, поскольку управление потоком данных не является исключительной ситуацией).
В зависимости от того, что вы пытаетесь сделать, бросок и ловля могут лучше соответствовать вашим потребностям, чем исключения.
class Example
RetryException = Class.new StandardError
BreakException = Class.new StandardError
attr_accessor :count
def initialize
self.count = 10
end
def rescue_block
yield
rescue RetryException
self.count -= 1
retry
rescue BreakException
self.count -= 2
return
end
def count_down
rescue_block { yield count while 0 < count }
end
end
Example.new.count_down do |count|
count # => 10, 9, 8, 7, 6, 5
raise Example::BreakException if count == 5
raise Example::RetryException
end
Example.new.count_down do |count|
count # => 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
raise Example::RetryException
end