In Ruby, What structures can a `rescue` statement be nested in
Asked Answered
A

2

41

In ruby to catch an error one uses the rescue statement. generally this statement occurs between begin and end. One can also use a rescue statement as part of a block (do ... end) or a method (def ... end). My question is what other structures (loop, while, if, ...) if any will rescue nest within?

Abduction answered 26/3, 2010 at 16:8 Comment(2)
do ... end blocks can't be rescued from without an explicit begin ... end.Yearlong
Since ruby 2.5 do ... end blocks can be rescued without an explicit begin ... end.Eustache
W
51

You can only use rescue in two cases:

  • Within a begin ... end block

    begin
      raise
    rescue 
      nil
    end
    
  • As a statement modifier

    i = raise rescue nil
    

Function, module, and class bodies (thanks Jörg) are implicit begin...end blocks, so you can rescue within any function without an explicit begin/end.

    def foo
      raise
    rescue
      nil
    end

The block form takes an optional list of parameters, specifying which exceptions (and descendants) to rescue:

    begin
      eval string
    rescue SyntaxError, NameError => boom
      print "String doesn't compile: " + boom
    rescue StandardError => bang
      print "Error running script: " + bang
    end

If called inline as a statement modifier, or without argument within a begin/end block, rescue will catch StandardError and its descendants.

Here's the 1.9 documentation on rescue.

Wing answered 26/3, 2010 at 17:28 Comment(5)
module and class bodies are implicit begin blocks, too.Stuartstub
@Jörg W Mittag: as are do ... end blocks and def ... end method definitions. IS there anything else that is an implicit begin? while, case, or if for example?Abduction
@john - do...end isn't an implicit begin...end.Wing
I suggest adding the comment above about do...end to the answer... that is really what I was looking for.Hophead
Although not very well documented, as of ruby 2.5 rescue works in regular do/end blocks (not in-line blocks {...} though). commitMeldameldoh
E
12

As said in recent comment, response has changed since Ruby 2.5.

do ... end blocks are now implicit begin ... end blocks; like module, class and method bodies.

In-line blocks {...} still can't.

Eustache answered 5/1, 2021 at 12:14 Comment(1)
my favorite is each blocksArdisardisj

© 2022 - 2024 — McMap. All rights reserved.