В чем разница при использовании обеспечения и еще после спасения?

  1. В чем разница между использованием ensure:

    begin
      foo_process
    rescue
      bar_process
    ensure
      baz_process
    end
    

    а поставить процесс после блока begin...rescue...end?

    begin
      foo_process
    rescue
      bar_process
    end
    baz_process
    
  2. В чем разница между использованием else:

    begin
      foo_process
    rescue
      bar_process
    else
      baz_process
    end
    

    и продолжить этот процесс до rescue (при условии, что baz_process не вызовет ошибку)?

    begin
      foo_process
      baz_process
    rescue
      bar_process
    end
    

person sawa    schedule 02.08.2013    source источник


Ответы (2)


1.

Используя ensure, baz_process всегда выполняется, даже если foo_process выдает исключение, возвращается из метода.

Например,

def foo_process
  puts 'foo_process'
  return 111
end

def f1
  begin
    return foo_process
  rescue 
    puts 'bar_process'
  ensure 
    puts 'baz_process'
  end
end

def f2
  begin
    return foo_process
  rescue 
    puts 'bar_process'
  end
  puts 'baz_process'
end

>> f1
foo_process
baz_process
=> 111
>> f2
foo_process
=> 111
person falsetru    schedule 02.08.2013
comment
Мне не понятен порядок выполнения. Включается ли блок ensure перед выполнением return? - person sawa; 02.08.2013
comment
@sawa, чтобы было понятно, я изменил код. Блок ensure выполняется непосредственно перед возвратом к вызывающей стороне. - person falsetru; 02.08.2013

Для вопроса 1 при использовании ensure всегда будет выполняться baz_process, даже если исключение не перехватывается блоком rescue (т. е. в вашем примере кода, даже если исключение не является StandardError). Он также будет запущен, если bar_process вызовет исключение. Ни то, ни другое не верно для кода, расположенного после блока begin...rescue...ensure.

Для вопроса 2 разница в том, что исключения, вызванные кодом в блоке else, не спасаются. Это более актуально, когда есть также блок обеспечения, так как код будет выполняться перед ним.

person Neil Slater    schedule 02.08.2013
comment
@sawa: Да, извините, я пропустил это предположение, но это немного сбивает с толку, чтобы сделать это требованием (немного похоже на то, почему нужно использовать условие перехода if x > y в предположении, что x всегда больше, чем y). Я мог бы утверждать, что ни один из кодов не вызывает ошибку, и в этом случае все варианты эквивалентны. Частично точка различия при использовании else в последовательности begin...rescue...ensure заключается в том, что вы хотите контролировать, какие части кода обрабатывают ошибки. - person Neil Slater; 05.08.2013