2012-04-08 3 views
5

Единственный случай использования, который я могу придумать для redo, был бы для операций, таких как запись в сокет или чтение из базы данных, но если они не будут выполняться один раз, последующие попытки, скорее всего, также потерпят неудачу, поэтому мне все еще кажется немного бессмысленным как для retry Я не могу думать о любом случае, где это было бы полезно.Какова цель повторных и повторных заявлений в Ruby?

Это может показаться мне бессмысленным с тех пор, как я не знаю или не использую Ruby, но я стремлюсь создать потрясающий язык в один прекрасный день, поэтому мне хотелось бы хотя бы узнать, что касается дизайна некоторых из самых популярных языков там.

+0

Ваше утверждение, что «последующие попытки, скорее всего, также не» кажется весьма спорным. Мне кажется, что это будет сильно зависеть от того, что не удалось и почему. Например, если причиной того, что ваш файл базы данных был тупиком, вызванным запросом, который кто-то еще запускал, отступает и повторная попытка - это именно то, что нужно сделать. –

ответ

8

Идея состоит в том, что вы что-то меняете перед тем, как позвонить redo или retry, в надежде, что все, что вы делаете, будет работать во второй раз. У меня нет примера для redo, но мы нашли применение для retry в приложении, над которым я работаю. В принципе, если у вас есть немного кода, который может выйти из строя из-за чего-то внешнего (например, сети), но выполнение проверки предварительного условия каждый раз, когда вы запускаете код, будет слишком дорого, вы можете использовать retry в блоке begin...rescue. Не уверен, что это было ясно, поэтому я вернусь к примеру.

В принципе, у нас есть код, который обращается к удаленному каталогу, используя Net:SFTP. Каталог должен существует, но в некоторых исключительных случаях он еще не был создан. Если его там нет, мы хотим попробовать сделать это один раз. Но выполнение сетевого доступа для проверки того, существует ли каталог каждый раз, будет слишком дорогостоящим, тем более, что только в исключительных случаях его там не будет. Таким образом, мы делаем это следующим образом:

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

Используйте случай для redo может быть проверен ввода пользователя:

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