2014-02-08 9 views
1

Я запускаю скрипт с API, который часто не хватает времени. Я использую блоки begin/rescue, чтобы получить его до redo, когда это произойдет, но вы хотите записать, что происходит с командной строкой, прежде чем я запустил команду redo.ruby ​​rescue block - ответьте не только на одну команду

begin 
#...api query... 
rescue ErrorClass 
    puts("retrying #{id}") && redo 
end 

К сожалению, указанный выше сценарий не работает. Выполняется только первая команда.

Я хотел бы, чтобы заставить спасательную блок для запуска нескольких строк кода, например, так:

begin 
# api query 
rescue ErrorClass do ###or:# rescue ErrorClass do |e| 
    puts "retrying #{id}" 
    redo 
end 

но те не работают либо.

Я имел счастье создавая отдельный метод для запуска, как так:

def example 
    id = 34314 
    begin 
    5/0 
    rescue ZeroDivisionError 
    eval(handle_zerodiv_error(id)) 
    end 
end 

def handle_zerodiv_error(id) 
    puts "retrying #{id}" 
    "redo" 
end 

... что на самом деле работает. Но для этого требуется слишком много строк кода, и он использует eval, который не является кошерным каким-либо образом в соответствии с моим наставником (ами).

+0

Какова цель 'redo' в коде, я не получаю то, что вы ищете –

+0

Большую часть времени я нахожусь в состоянии начать процесс снова при этом указанном id, что ошибка произошла и работает. Таким образом, я пытаюсь сделать это без нарушения сценария. Там неизбежно будут некоторые случаи, когда сама команда API вызывает ошибку, поэтому я хочу знать, когда скрипт застревает на одном и том же идентификаторе. –

+0

* Я хотел бы заставить блок спасения запустить несколько строк кода * - в чем проблема? Вы имеете в виду последнюю строку, не выполняющую? –

ответ

2

Вы излишне усложнять с помощью && или do. Версия && не работает, потому что puts возвращает nil, поэтому по ярлыку оценки &&, часть, которую следует выполнить, не оценивается. Если вы используете || или ; вместо этого, то он будет работать:

begin 
    ... 
rescue ErrorClass 
    puts("retrying #{id}") || redo 
end 

begin 
    ... 
rescue ErrorClass 
    puts("retrying #{id}"); redo 
end 

, но даже это не является необходимым. Вы как-то думаете, что вам нужен блок в пределах rescue, чтобы написать несколько строк, но это не имеет смысла, потому что вы не используете блок с одной строкой. Нет конструкции Ruby, которая требует блока только тогда, когда у вас есть несколько строк. Так, просто положить их в нескольких строках:

begin 
    ... 
rescue ErrorClass 
    puts("retrying #{id}") 
    redo 
end 
1

Существует retry встроенный. Этот пример из «Рубина» Язык программирования стр 162.

require "open-uri" 

tries = 0 
begin 
    tries +=1 
    open("http://www.example.com/"){|f| puts f.readlines} 
rescue OpenURI::HTTPError => e 
    puts e.message 
    if (tries < 4) 
    sleep (2**tries) # wait for 2, 4 or 8 seconds 
    retry    # and try again 
    end 
end 
+0

Я думаю, что 'retry' снова пытается перечислить всю группу' Enumerable' ('array'),' redo' снова повторяет заданный член 'Enumberable' (' array [n] ') –

 Смежные вопросы

  • Нет связанных вопросов^_^