Рубиновый спасательный блок или класс
Кажется, я снова использую то же самое rescue
s. Было бы возможно иметь 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