Рубиновый спасательный блок или класс

Кажется, я снова использую то же самое rescues. Было бы возможно иметь rescue блок? Так что вместо:

while count != 0 do 
<<code>>
rescue error1
<<code>>
retry
rescue error2
<<code>>
break
end

Я могу иметь:

def rescue_block
rescue error 1
<<code>>
retry
rescue error 2
<<code>>
break
end

while count !=0
<<code>>
rescue_block
end

Обратите внимание на break а также retry, rescue_block Действия должны применяться к циклу, а не к самому себе.

РЕДАКТИРОВАТЬ:

Используя драгоценный камень Twitter, большинство ошибок Twitter могут быть обработаны таким же образом (например, если вы достигнете предела API, подождите.). Полный код:

while cursor != 0 do
  begin
    grabFollowers ? f = Twitter.follower_ids(username,{:cursor=>cursor}) : f = Twitter.friend_ids(username,{:cursor=>cursor})
    outfile.puts(f.ids) if writeHumanReadable
    arrayOfIds << f.ids
    cursor = f.next_cursor
  rescue Twitter::Error::Unauthorized
    break
  rescue Twitter::Error::BadRequest
    #ran out of OAUTH calls, waits until OAUTH reset + 10 seconds.
    outErrorFile = File.new("#{username.to_s}-ERROR.txt",'w')
    resetTime = Twitter.rate_limit_status.reset_time_in_seconds
    current = Time.now.to_i
    pauseDuration = resetTime-current+10
    outErrorFile.puts(Time.now)
    outErrorFile.puts(pauseDuration/60)
    outErrorFile.close
    sleep(pauseDuration)
    retry
  rescue Twitter::Error::NotFound
    break
  rescue Twitter::Error::ServiceUnavailable
    sleep(60*5)
    retry
  end
  sleep(2)
end

1 ответ

Решение

Ваш пример показывает, что вам нужны макросы, которых нет в 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
Другие вопросы по тегам