raising - ruby rescue multiple exceptions




Qual é a diferença entre Aumentar Exceções e Arremessar Exceções no Ruby? (2)

Eu acho que http://hasno.info/ruby-gotchas-and-caveats tem uma explicação decente da diferença:

catch / throw não são o mesmo que raise / rescue. catch / throw permite que você rapidamente retire os blocos de volta a um ponto em que uma captura é definida para um símbolo específico, raise rescue é a verdadeira exceção que manipula as coisas envolvendo o objeto Exception.

Ruby tem dois mecanismos diferentes de exceção: Throw / Catch e Raise / Rescue.

Por que temos dois?

Quando você deve usar um e não o outro?


https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise oferece uma excelente explicação que duvido que possa melhorar. Para resumir, escolhendo algumas amostras de código da postagem do blog à medida que eu vou:

  1. raise / rescue são os análogos mais próximos da construção throw / catch você está familiarizado de outras linguagens (ou para o raise / except do Python). Se você encontrou uma condição de erro e throw em outro idioma, deverá raise em Ruby.

  2. O throw / catch Ruby permite que você quebre a execução e suba na pilha procurando por uma catch (como raise / rescue ), mas não se destina a condições de erro. Ele deve ser usado raramente, e existe apenas quando o comportamento de "subir na pilha até encontrar uma catch correspondente" faz sentido para um algoritmo que você está escrevendo, mas não faria sentido pensar no throw como correspondendo a um algoritmo. uma condição de erro.

    O que é pegar e jogar usado em Ruby? oferece algumas sugestões sobre bons usos da construção throw / catch .

As diferenças comportamentais concretas entre eles incluem:

  • rescue Foo irá resgatar instâncias de Foo incluindo subclasses de Foo . catch(foo) só vai pegar o mesmo objeto, Foo . Não apenas você não pode passar um nome de classe para capturar instâncias dele, mas também não fará comparações de igualdade. Por exemplo

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

    lhe dará um UncaughtThrowError: uncaught throw "foo" (ou um ArgumentError em versões do Ruby anteriores a 2.2)

  • Várias cláusulas de resgate podem ser listadas ...

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

    enquanto várias catch precisam ser aninhadas ...

    catch :foo do
      catch :bar do
        do_something_that_can_throw_foo_or_bar
      end
    end
  • Um simples rescue é equivalente a rescue StandardError e é uma construção idiomática. Uma " catch nua", como catch() {throw :foo} , nunca vai pegar nada e não deve ser usada.







exception