В чем разница между созданием исключений и выбрасыванием исключений в Ruby?



Ruby имеет два разных механизма исключений: бросок/улов и подъем / спасение.



Почему у нас есть два?



когда вы должны использовать один и не другой?

506   3  

3 ответов:

Я думаю http://hasno.info/ruby-gotchas-and-caveats имеет достойное объяснение разницы:

поймать / бросить не то же самое, что поднять/спасти. catch / throw позволяет быстро выходить из блоков обратно в точку, где catch определен для определенного символа, raise rescue-это реальный материал обработки исключений, включающий объект исключения.

  • raise,fail,rescue и ensure дескриптор ошибки, также известный как исключения
  • throw и catch are поток управления

в отличие от других языки, Руби throw и catch не используются для исключения. Вместо этого они предоставляют способ досрочного завершения выполнения, когда нет необходима дальнейшая работа. (Grimm, 2011)

завершение один уровень потока управления, например while цикл, можно сделать с помощью простого return. Завершение многих уровней потока управления, таких как вложенный цикл, можно выполнить с помощью throw.

хотя механизм исключения raise и rescue отлично подходит для отказа от выполнения, когда все идет не так, иногда приятно иметь возможность выпрыгнуть из какой-то глубоко вложенной конструкции во время обычной обработки. Это где поймать и бросить пригодится. (Томас и Хант, 2001)

ссылки

  1. Гримм, Авди. "Бросай, Лови, поднимай, спасай... я так запуталась!"Блог RubyLearning. Н. П., 11 июля 2011 года. Сеть. 1 января. 2012. http://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue--im-so-confused/.
  2. Томас, Дэйв и Эндрю Хант. - Программирование Руби.": Руководство прагматичного программиста. N. p., 2001. Сеть. 29 сентября. 2015. http://ruby-doc.com/docs/ProgrammingRuby/html/tut_exceptions.html.

https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise предлагает отличное объяснение, которое я сомневаюсь, что могу улучшить. Подводя итог, отмечу некоторые примеры кода из сообщения в блоге, когда я иду:

  1. raise/rescue являются ближайшими аналогами throw/catch построить вы знакомы с другими языками (или на Python raise/except). Если вы столкнулись с условием ошибки, и вы бы throw над ним на другом языке, вы должны raise в Руби.

  2. Рубин throw/catch позволяет прервать выполнение и подняться вверх по стеку ищем catch (типа raise/rescue делает), но на самом деле не предназначен для условий ошибки. Он должен использоваться редко, и есть только для того, когда " поднимитесь по стеку, пока не найдете соответствующий catch" поведение имеет смысл для алгоритма, который вы пишете, но не имеет смысла думать о throw как соответствует условию ошибки.

    для чего используется catch and throw в Ruby? предлагает некоторые предложения по хорошему использованию throw/catch строительство.

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

  • rescue Foo спасет экземпляров Foo в том числе подклассы Foo. catch(foo) только поймать один и тот же объект, Foo. Не только вы не можете пас catch имя класса, чтобы поймать его экземпляры, но он даже не будет делать сравнения равенства. Например,

    catch("foo") do
      throw "foo"
    end
    

    вы UncaughtThrowError: uncaught throw "foo" (или ArgumentError в версиях Ruby до 2.2)

  • несколько пунктов спасения могут быть перечислены...

    begin
      do_something_error_prone
    rescue AParticularKindOfError
      # Insert heroism here.
    rescue
      write_to_error_log
      raise
    end
    

    в то время как несколько catch es должны быть вложенными...

    catch :foo do
      catch :bar do
        do_something_that_can_throw_foo_or_bar
      end
    end
    
  • голой rescue эквивалентно rescue StandardError и является идиоматической конструкцией. Один - голый catch", как catch() {throw :foo}, никогда ничего не поймает и не должен использоваться.

Comments

    Ничего не найдено.