Feature #8239

Inline rescue bug

Added by David Unric about 1 year ago. Updated about 1 year ago.

[ruby-core:54120]
Status:Open
Priority:Normal
Assignee:Yukihiro Matsumoto
Category:syntax
Target version:-

Description

There is a possible bug in parsing of inline rescue.
When an inline rescue is a part of multiple assignment and exception is raised, the assignment is silently ignored.

def foo
raise "error"
end

bar, baz = 1,2 # bar == 1, baz == 2
bar, baz = foo rescue [3,4] # no assignment performed: bar == 1, baz == 2
# expected after the expression: bar == 3, baz == 4

Already discussed at stackoverflow.com:
http://stackoverflow.com/questions/15880136/exceptions-why-does-adding-parenthesis-change-anything


Related issues

Duplicated by ruby-trunk - Bug #8279: Single-line rescue parsing Open 04/16/2013

History

#1 Updated by Hans Mackowiak about 1 year ago

its because its parsed as
(bar, baz = foo) rescue [3,4]
i try
bar, baz = (foo rescue [3,4])
and this works

#2 Updated by Nobuyoshi Nakada about 1 year ago

  • Priority changed from High to Normal

=begin
Not only this case, some assignments can't include (({rescue})) modifier, e.g.:

x = 1
x += raise rescue 2

makes ((|x|)) (({3})), while

x = [1]
x[0] += raise rescue 2

doesn't change ((|x|)).

It would be possible to make them consistent all, but obviously causes
an incompatibility.

=end

#3 Updated by David Unric about 1 year ago

Hanmac (Hans Mackowiak) wrote:

its because its parsed as
(bar, baz = foo) rescue [3,4]
i try
bar, baz = (foo rescue [3,4])
and this works

I think this explanation is not valid. Let's see on an example:

bar = foo rescue [3,4]
If it would be parsed as you've described it would be equivalent to
(bar = foo) rescue [3,4]
but in contrary the assignment is performed !
ie. bar == [3,4] now.

I did pointed out the issue concerns the case of multiple assignment expression.

#4 Updated by David Unric about 1 year ago

nobu (Nobuyoshi Nakada) wrote:

=begin
Not only this case, some assignments can't include (({rescue})) modifier, e.g.:

x = 1
x += raise rescue 2

makes ((|x|)) (({3})), while

x = [1]
x[0] += raise rescue 2

doesn't change ((|x|)).

It would be possible to make them consistent all, but obviously causes
an incompatibility.

=end

I can confirm this behaviour. This is another example parsing of expression with inline rescue is broken.

I would like to see at least one real world example relying on this inconsistent behaviour. I don't expect fixing this bug would cause any incompatibility. Prove me wrong.

#5 Updated by Yui NARUSE about 1 year ago

  • Tracker changed from Bug to Feature

#6 Updated by David Unric about 1 year ago

Hi,

any explanation why marked as a feature (request) instead of bug (of Ruby parser) ?

Thanks.

#7 Updated by Jason Woodard about 1 year ago

I'd also vote for a bug to fix. I do not find it a feature request to implement.
There is nowhere in the documentation confirming the current behaviour to be correct.

#8 Updated by Nobuyoshi Nakada about 1 year ago

I also think this is a bug, but it may not be backported because of backward compatibility.

Also available in: Atom PDF