Ruby救援块或类

时间:2012-02-04 18:54:47

标签: ruby exception-handling rescue

我似乎正在重复使用相同的rescue。是否可能有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

注意breakretryrescue_block操作需要应用于循环,而不是自身。

编辑:

使用Twitter gem,大多数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 个答案:

答案 0 :(得分:3)

你的例子让它看起来像你想要的宏,Ruby没有。

我们可以使用块来接近您的示例,但在不知道您的用例的情况下很难回答这个问题。 (我想你没有使用流程控制的例外,因为流量控制不是特殊的情况,这通常是不受欢迎的。)

根据你想要做的事情,throw和catch可能比异常更适合你的需求。

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