2012-04-08 6 views
5

L'unico caso di utilizzo a cui posso pensare per redo potrebbe essere per operazioni come scrivere in un socket o leggere da un database, ma se questi falliscono una volta, anche i tentativi successivi probabilmente falliranno quindi sembra ancora un po 'inutile per me e per quanto riguarda retry non riesco davvero a pensare a nessun caso in cui sarebbe utile.Qual è lo scopo delle istruzioni di ripetizione e riprova in Ruby?

Questo potrebbe sembrare insignificante per me dal momento che non conosco o utilizzo Ruby, ma aspiro a creare un linguaggio fantastico un giorno quindi vorrei almeno conoscere il ragionamento dietro la progettazione di alcune delle lingue più popolari fuori Là.

+0

tua affermazione che "i tentativi successivi saranno molto probabilmente anche fallire" sembra altamente discutibile. Mi sembra che questo dipenda molto da cosa ha fallito e perché. Ad esempio, se il motivo per cui il file di operazione del database era un deadlock causato dalla query che qualcun altro stava eseguendo, allora il back-off e il nuovo tentativo sono esattamente la cosa giusta da fare. –

risposta

8

L'idea è di cambiare qualcosa prima di chiamare redo o retry, nella speranza che tutto ciò che stavate facendo funzionasse per la seconda volta. Non ho un esempio per redo, ma abbiamo trovato usi per retry nell'applicazione su cui sto lavorando. In sostanza, se si dispone di un bit di codice che potrebbe non riuscire a causa di qualcosa di esterno (ad es. Rete), ma eseguire un controllo di precondizione ogni volta che si esegue il codice sarebbe troppo costoso, è possibile utilizzare retry in un blocco begin...rescue. Non sono sicuro che sia chiaro, quindi avrò ragione nell'esempio.

Fondamentalmente, abbiamo un codice che accede a una directory remota usando Net:SFTP. La directory dovrebbe essere, ma in alcuni casi eccezionali non è stata ancora creata. Se non è lì, vogliamo provare una volta a farlo. Ma eseguire l'accesso alla rete per verificare se la directory esiste ogni volta sarebbe troppo costoso, soprattutto perché è solo in casi eccezionali che non ci sarà. Così lo facciamo nel modo seguente:

tried_mkdir = false 
begin 
    # Attempt to access remote directory 
    ... 
rescue Net::SFTP::StatusException 
    raise if tried_mkdir 
    tried_mkdir = true 
    # Attempt to make the remote directory 
    ... 
    retry 
end 
6

Caso d'uso per redo potrebbe essere controllare l'input dell'utente:

nums = Array.new(5){[rand(1..9), rand(1..9)]} 
nums.each do |num1, num2| 
    print "What is #{num1} + #{num2}: " 
    redo unless gets.to_i == num1 + num2 
end