Rescue clauses on do/end blocks?


#1

I know this has been on the table before, but I really see no reason not
to allow do/end blocks to have rescue clauses on them, i.e.

foo do
bar
rescue
baz
end

and even

foo do
bar
rescue
baz
ensure
bur
end

These would be equivalent to

foo do
begin
bar
rescue
baz
ensure
bur
end
end

When an ensure clause is added, the expression evaluated therein will
always be the return value of a call to the block – just as if there
was a begin/end block inside the do/end block.

This wouldn’t offer any new functionality, but would make the use of
rescue and ensure clauses more consistent – currently they work with
begin, class, and def blocks (more?).

There’s of course the case of the curly bracket block syntax, but I see
no need to support it there – I think it’s most commonly used with
one-liners, where rescuing may be overkill.

I’d like some feedback, and if its generally positive, I’ll post an RCR.

Cheers,
Daniel


#2

2006/5/18, Daniel S. removed_email_address@domain.invalid:

I’d like some feedback, and if its generally positive, I’ll post an RCR.

Go for it!

robert


#3

On 5/18/06, Daniel S. removed_email_address@domain.invalid wrote:

I know this has been on the table before, but I really see no reason not
to allow do/end blocks to have rescue clauses on them, i.e.

I’ve tried that syntax myself and been surprised when it failed. It
seems
like less typing to me- usually a good thing!

Justin


#4

Ross B. wrote:

Just playing Devil’s Advocate, what’d happen with this:

File.open(‘somefile’) do |f|
puts f.read
end rescue puts “Can’t open”

The same as there would now; since the rescue clause is not inside the
do/end block, it is not affected by this proposal.

The difference would be that your version would also rescue exceptions
raised by File.open, while the proposed syntax would only rescue
exceptions raised within the block given to File.open.

But I like the devil’s advocate approach, it makes the proposals sharper
:slight_smile:

Daniel


#5

Robert K. wrote:

2006/5/18, Daniel S. removed_email_address@domain.invalid:

I’d like some feedback, and if its generally positive, I’ll post an RCR.

Go for it!

Alrighty then!

http://www.rcrchive.net/rcr/show/336

Cheers,
Daniel


#6

On Thu, 2006-05-18 at 23:55 +0900, Daniel S. wrote:

I know this has been on the table before, but I really see no reason not
to allow do/end blocks to have rescue clauses on them, i.e.

foo do
bar
rescue
baz
end

Just playing Devil’s Advocate, what’d happen with this:

File.open('somefile') do |f|
  puts f.read
end rescue puts "Can't open"

?


#7

Ross B. wrote:

On Thu, 2006-05-18 at 23:55 +0900, Daniel S. wrote:

I know this has been on the table before, but I really see no reason not
to allow do/end blocks to have rescue clauses on them, i.e.

foo do
bar
rescue
baz
end

Just playing Devil’s Advocate, what’d happen with this:

File.open(‘somefile’) do |f|
puts f.read
end rescue puts “Can’t open”

?

What if rescue has more than one sentence? It seems not a good idea.
But I agree with Daniel S.'s proposal.


#8

uncutstone wu wrote:

Ross B. wrote:

On Thu, 2006-05-18 at 23:55 +0900, Daniel S. wrote:

I know this has been on the table before, but I really see no reason not
to allow do/end blocks to have rescue clauses on them, i.e.

foo do
bar
rescue
baz
end

Just playing Devil’s Advocate, what’d happen with this:

File.open(‘somefile’) do |f|
puts f.read
end rescue puts “Can’t open”

?

What if rescue has more than one sentence? It seems not a good idea.
But I agree with Daniel S.'s proposal.

I think the syntax would be changed as below:
File.open(‘somefile’) do |f|
puts f.read
rescue
puts “Can’t open”
end


#9

On Fri, 2006-05-19 at 00:34 +0900, Daniel S. wrote:

raised by File.open, while the proposed syntax would only rescue
exceptions raised within the block given to File.open.

Does that mean that with the proposed syntax, to rescue an exception
from this File.open, we’d have to use:

begin
  File.open('somefile') do |f|
    puts f.read
  rescue
    # exception from f.read
  end
rescue
  # exception from File.open
end

But I like the devil’s advocate approach, it makes the proposals sharper :slight_smile:

:slight_smile: In truth, I think I’m in favour of this change, especially if it
could be done so that the rescue catches exceptions from the block as
well
as those from the method to which the block is attached (if any).


#10

On 5/18/06, Daniel S. removed_email_address@domain.invalid wrote:

I know this has been on the table before, but I really see no reason not
to allow do/end blocks to have rescue clauses on them, i.e.

The main reason that Matz has opposed it before is:

foo {
bar
rescue
baz
}

It does look odd, but I think people will just get used to it.

-austin


#11

uncutstone wu wrote:

I think the syntax would be changed as below:
File.open(‘somefile’) do |f|
puts f.read
rescue
puts “Can’t open”
end

Rather:

File.open(‘pr0n’) do |f|
puts f.read
rescue
puts “can’t read”
end

since we won’t rescue any exceptions raised by File.open, only those
raised by File#read.

Daniel


#12

On May 18, 2006, at 7:55 AM, Daniel S. wrote:

I know this has been on the table before, but I really see no
reason not to allow do/end blocks to have rescue clauses on them, i.e.

foo do
bar
rescue
baz
end

[…]

I’d like some feedback, and if its generally positive, I’ll post an
RCR.

Setting up and tearing down an exception handler for every block
invocation is going to be expensive.

I vote no.


Eric H. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com


#13

Ross B. wrote:

# exception from File.open

end

As I imagine it right now, rescue clauses on do/end blocks would only
rescue exceptions raised inside that block – to rescue exceptions
raised with the method the block is attached to, one must wrap the
method with begin/end.

But I like the devil’s advocate approach, it makes the proposals sharper :slight_smile:

:slight_smile: In truth, I think I’m in favour of this change, especially if it
could be done so that the rescue catches exceptions from the block as
well
as those from the method to which the block is attached (if any).

I’m not sure I’d like that – I see a block attached to a method call as
being, in some sense, a child of that call, another kind of argument if
you will; having the child rescue exceptions raised by the parent seems
unintuitive to me, though others may feel different.

People, feel free to chime in.

Daniel


#14

Eric H. wrote:

Setting up and tearing down an exception handler for every block
invocation is going to be expensive.

Couldn’t the setup/teardown be done only if a rescue/ensure clause was
actually present? It also seems to me that this would mean the the
setup/teardown would have to be in the block itself, not in the calling
method. Thus making it hard to rescue exceptions from the calling
method (as some have suggested).

For the record,

(A) if it can be done efficiently, I’m for it.
(B) I’m not in favor of rescuing exceptions from the parent method.
That just seems backwards to me.


– Jim W.


#15

Austin Z. wrote:

The main reason that Matz has opposed it before is:

foo {
bar
rescue
baz
}

It does look odd, but I think people will just get used to it.

I think it looks too odd. The do/end and the curly bracket syntaxes are
used in different places – if I needed error handling, I would never
use the curly brackets anyway. I see the problem, though; I just don’t
think it’s big enough to block the implementation of this.

Daniel


#16

Daniel S. wrote:

:slight_smile: In truth, I think I’m in favour of this change, especially if it
could be done so that the rescue catches exceptions from the block as
well
as those from the method to which the block is attached (if any).

I’m not sure I’d like that – I see a block attached to a method call as
being, in some sense, a child of that call, another kind of argument if
you will; having the child rescue exceptions raised by the parent seems
unintuitive to me, though others may feel different.

I agree with Daniel. It should only rescue exceptions raised in the
block, not the parent/holder/caller/receiver of the block.

Pistos


#17

Hi –

On Fri, 19 May 2006, Daniel S. wrote:

I think it looks too odd. The do/end and the curly bracket syntaxes are used
in different places – if I needed error handling, I would never use the
curly brackets anyway.

I’m not sure I get that distinction – I mean, I understand that you
do it that way, but I’m not sure there’s any generally closer
association between do/end and rescuing than there is between {} and
rescuing. Also, they’re sometimes used in the same places, but by
different people :slight_smile:

David


#18

On May 18, 2006, at 12:58 PM, Daniel S. wrote:

are used in different places
Not true. do/end and {/} are interchangeable except you may need to
add () for precedence.


Eric H. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com


#19

Eric H. wrote:

Setting up and tearing down an exception handler for every block
invocation is going to be expensive.

I vote no.

Wouldn’t it be possible to only set up an exception handler for blocks
that actually have rescue clauses?

Daniel


#20

On May 18, 2006, at 11:22 AM, Jim W. wrote:

Eric H. wrote:

Setting up and tearing down an exception handler for every block
invocation is going to be expensive.

Couldn’t the setup/teardown be done only if a rescue/ensure clause was
actually present? It also seems to me that this would mean the the
setup/teardown would have to be in the block itself, not in the
calling
method.

I forgot that the parser will just take care of it. The patch was
easy, applies to a recentish copy of the 1.8 branch: