Feature #7882

Allow rescue/else/ensure in do..end

Added by Charlie Somerville about 1 year ago. Updated 3 months ago.

[ruby-core:52513]
Status:Assigned
Priority:Normal
Assignee:Yukihiro Matsumoto
Category:-
Target version:current: 2.2.0

Description

=begin
The keywords (({rescue})), (({else})) and (({ensure})) can be used when defining methods like so:

def foo
#
rescue
#
else
#
ensure
#
end

However when using a block delimited by do..end, you must use (({begin}))..(({end})) as well:

foo do
begin
# ...
rescue
# ...
# ...
end
end

It would be nice to be able to drop the extra (({begin}))..(({end})) and use (({rescue})), etc. clauses directly:

foo do
# ...
rescue
# ...
# ...
end

I cannot think of any ambiguities this syntax would cause, but please correct me if I am wrong.
=end

History

#1 Updated by Nobuyoshi Nakada about 1 year ago

=begin
I remember I've seen the same proposal.

What do you think about {} block?

foo {
...
rescue
...
}

seems odd to me a little.

Or improve (({do}))...(({end})) only?
=end

#2 Updated by Rodrigo Rosenfeld Rosas about 1 year ago

I don't find it that odd, Nobu, although I think most developers would tend to use do-end anyway as we usually do in Ruby when the block span multiple lines.

I like the idea very much actually.

#3 Updated by Yusuke Endoh about 1 year ago

  • Status changed from Open to Assigned
  • Assignee set to Yukihiro Matsumoto

I have suggested the same proposal (in Japanese ).
Matz said in that it is not clear (to him) whether:

loop do
:
rescue
:
ensure
:
end

should behave like:

begin
loop do
:
end
rescue
:
ensure
:
end

or:

loop do
begin
:
rescue
:
ensure
:
end
end

Yusuke Endoh mame@tsg.ne.jp

#4 Updated by Alexey Muranov about 1 year ago

I've heard of a convention to use { ... } for blocks evaluated for a result and do ... end for blocks evaluated for side effects: http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc
From this point of view, there probably shouldn't be any differences in the syntax inside the two forms of blocks.

#5 Updated by Rodrigo Rosenfeld Rosas about 1 year ago

Yusuke, I believe it should be the latter. If you want to rescue from the yielding method you have the option of doing it like this in most cases:

withtransaction do
...
rescue
...
end rescue puts 'with
transaction raised outside the yield block'

#6 Updated by Matthew Kerwin 10 months ago

mame (Yusuke Endoh) wrote:

I have suggested the same proposal (in Japanese ).
Matz said in that it is not clear (to him) ...

Definitely the latter. The rescue statement in the block should only rescue errors that occur inside the block. This is more apparent if you consider that:

loop do
rescue
finally
end

is equivalent to:

x = proc do
rescue
finally
end
while true
x.call
end

Similarly replacing 'while' with a method, such as #each; the 'rescue' in the block should not expect to catch exceptions in the implementation of 'each', only the exceptions raised in the body of the block.

#7 Updated by Hiroshi SHIBATA 3 months ago

  • Target version changed from 2.1.0 to current: 2.2.0

Also available in: Atom PDF