From: shevegen@... Date: 2019-01-26T12:03:24+00:00 Subject: [ruby-core:91283] [Ruby trunk Feature#15567] Allow ensure to match specific situations Issue #15567 has been updated by shevegen (Robert A. Heiler). I was about to write a long comment, but then I noticed that my reply would be too long, so I shortened this. So just a few key statements: - I don't like the proposed syntax suggestion here in particular: ensure when not return The reason why I dislike it is partially due to the syntax verbosity; but also because, more significantly, because it appears to do conditional checks in very different means than have existed before in ruby. I would expect "when" usually in a case-structure. There was this other recent suggestion to also add "when", to allow for chaining after the addition of the alias "then" to "yield_self", leading to chains of .when .then .when .then; and I also am not a huge fan of using "when" that way. Of course there is more than one way to do something, but my own personal preference would be to keep "when" reserved for case-when layouts. As for catch/throw: I think it is a lot more common to see begin/rescue than catch/throw. Even if this may be slower (e. g. some people doing control flow logic with begin/rescue), I think the intent and clarity of intent is much clearer with control flows based on begin/rescue (and ensure) style layout of code. So to conclude and finish my comment, I think it would be better to not introduce a more complicated ensure conditional clause as proposed in the suggestion here. IMO you can re-structure your code to keep ensure simple, so it should not be necessary to add additional conditionals into ensure, even more so when these are unusual in regards to syntax - it would be the first time that I would see "ensure when" and I don't quite like that syntax suggestion in this context. ---------------------------------------- Feature #15567: Allow ensure to match specific situations https://bugs.ruby-lang.org/issues/15567#change-76531 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal * Assignee: ioquatix (Samuel Williams) * Target version: ---------------------------------------- There are some situations where `rescue Exception` or `ensure` are not sufficient to correctly, efficiently and easily handle abnormal flow control. Take the following program for example: ``` def doot yield ensure # Did the function run to completion? return "abnormal" if $! end puts doot{throw :foo} puts doot{raise "Boom"} puts doot{"Hello World"} catch(:foo) do puts doot{throw :foo} end ``` Using `rescue Exception` is not sufficient as it is not invoked by `throw`. Using `ensure` is inefficient because it's triggered every time, even though exceptional case might never happen or happen very infrequently. I propose some way to limit the scope of the ensure block: ``` def doot yield ensure when raise, throw return "abnormal" end ``` The scope should be one (or more) of `raise`, `throw`, `return`, `next`, `break`, `redo`, `retry` (everything in `enum ruby_tag_type` except all except for `RUBY_TAG_FATAL`). Additionally, it might be nice to support the inverted pattern, i.e. ``` def doot yield ensure when not return return "abnormal" end ``` Inverted patterns allow user to specify the behaviour without having problems if future scopes are introduced. `return` in this case matches both explicit and implicit. -- https://bugs.ruby-lang.org/ Unsubscribe: