From: "zverok (Victor Shepelev)" Date: 2022-10-14T16:14:17+00:00 Subject: [ruby-core:110286] [Ruby master Misc#19054] `else` in exception-handling context vs early return Issue #19054 has been updated by zverok (Victor Shepelev). Well, my pseudo-code-expressed intuition can be rather expressed like this: ```ruby begin # whatever happens here, is covered by rescue/else/ensure block e = exception_raised_by{puts "body"; return} ensure if e # we go here if there was an exception p e else # we go here if there was none puts "else" end # we go here in any case puts "ensure" end ``` It is implied by `else` and `rescue` being on the same level as `ensure`, making me think there are 3 blocks of equal priority * one that performs always (`ensure`) * one that performs if there was exception ([one of the] `rescue`) * one that performs if there was no exception (`else`) If we'll imagine more realistic code, there can be, like, 30 lines of methods body, and overall structure on reading looking like this: ```ruby def my_method # a LOT can go here, # ...but while reading # ...to the very end # ...you can always rely # ...on the fact that # even if THIS last line is not performed due to some reason, rescue # this WILL perform if any exception happens, however deep it was else # this WILL perform if no exception happened, no matter what ensure # this WILL perform no matter what, period end ``` Again, for me it somewhat theoretical, but I can imagine good uses for `else` like, at the very least, `log.debug 'success'`. With current behavior, it seems completely redundant feature, because imagine this: ```ruby def my_method return :early puts "(1) printed at the end in normal, no early return-flow" :regular rescue # ... else puts "I would hope this will print for both :early, and :regular, but it behaves JUST like (1)" end ``` ...e.g. NOTHING is achieved by `else` that can't be achieved by putting exactly the same code at the end of the body. ---------------------------------------- Misc #19054: `else` in exception-handling context vs early return https://bugs.ruby-lang.org/issues/19054#change-99572 * Author: zverok (Victor Shepelev) * Status: Open * Priority: Normal ---------------------------------------- `else` in exception-handling context is rarely used (at least in codebase I saw), so we encountered it just recently: ```ruby def foo puts "body" return rescue => e p e else puts "else" ensure puts "ensure" end foo # prints "body", then "ensure" [1].each do puts "body" next rescue => e p e else puts "else" ensure puts "ensure" end # also prints "body" then "ensure" ``` E.g. `else` is ignored in both cases. Intuitively, I would expect that if no exception is raised in block, `else` is performed always���like `ensure` is performed always, exception or not, early return or not. I found only a very old discussion of this behavior in #4473 (it was broken accidentally on the road to 1.9.2, but then fixed back), but it doesn't explain the reason for it. Can somebody provide an insight on this decision, and whether it is justified at all?.. At least, it should be documented somewhere, [exception handling docs](https://docs.ruby-lang.org/en/master/syntax/exceptions_rdoc.html) doesn't mention this quirk. -- https://bugs.ruby-lang.org/ Unsubscribe: