Project

General

Profile

Actions

Feature #15567

closed

Allow ensure to match specific situations

Added by ioquatix (Samuel Williams) over 2 years ago. Updated 30 days ago.

Status:
Rejected
Priority:
Normal
Target version:
-
[ruby-core:91287]

Description

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.


Related issues

Related to Ruby master - Feature #18083: Capture error in ensure block.OpenActions
Actions

Also available in: Atom PDF