Project

General

Profile

Actions

Bug #16092

closed

[doc] precedence of modifier-rescue

Added by Dan0042 (Daniel DeLorme) over 4 years ago. Updated over 4 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:94221]

Description

The docs state that modifier-rescue has higher precedence than assignments which have higher precedence than modifier-if. This is true for
v = expr rescue $! if condition but not for
v = expr if condition rescue $! which is treated as
(v = expr if condition) rescue $! rather than
v = expr if (condition rescue $!)

This goes similarly for
defined? expr rescue $!
not expr rescue $!
expr1 and expr2 rescue $!
expr1 or expr2 rescue $!

So maybe the documentation should state that modifier-rescue has equal precedence to modifier-if & others, with an exception made for assignments? I'm not entirely sure how to describe that exception though.


Files

modifier-statements.patch (3.74 KB) modifier-statements.patch Dan0042 (Daniel DeLorme), 08/09/2019 06:45 PM

Updated by mame (Yusuke Endoh) over 4 years ago

  • Status changed from Open to Rejected

The current doc about precedence is correct. The behavior you showed is not caused by precedence, but by the grammer itself.

The point is, that <stmt> rescue <stmt> is a statement, not an expression. The right side of modifier-if must be an expression, so <stmt> rescue <stmt> cannot be a right side of modifier-if. So, <stmt> if <stmt> rescue <stmt> can parse only as (<stmt> if <stmt>) rescue <stmt>.

defined? also requires an expression as its argument. So defined? expr rescue $! can parse only as defined? (expr rescue $!).

You can see the precedence by the following code: stmt if v = condition rescue $!. It can parse as both (stmt if v = condition) rescue $! and stmt if v = (condition rescue $!) but the second one is chosen because modifier-rescue has higher precedence than modifier-if.

Updated by Dan0042 (Daniel DeLorme) over 4 years ago

Ok, I'm starting to see. The difference between statements and expressions is why we get this

puts( 1 if 2 )   #=> SyntaxError
puts((1 if 2))   #=> 1
puts(if 2;1;end) #=> 1   ...interesting
puts( 1 rescue 2 ) #=> SyntaxError
puts((1 rescue 2)) #=> 1
defined?(1 rescue 2)  #=> SyntaxError
defined? (1 rescue 2) #=> "expression"

So a if b rescue c is parsed as ‹a if b› rescue c because a if ‹b rescue c› would be a SyntaxError.

In any case, even if the issue is not precedence itself, I think the documentation should be updated somehow, because it leads one to think that a if b rescue c is equivalent to a if (b rescue c)

Now that I understand the nature of the issue I've tried writing a documentation patch.

Actions #3

Updated by jeremyevans (Jeremy Evans) over 4 years ago

  • Status changed from Feedback to Closed

Applied in changeset git|29c1e9a0d4c855781853f0ad41b0125f42cf504d.


Document the difference between expressions and statements [ci skip]

In the grammar, all expressions are statements, but not all
statements are expressions. Some parts of the grammar accept
expressions and not other types of statements, which causes
similar looking code to parse differently due to operator
precedence.

Mostly from Dan0042 (Daniel DeLorme).

Fixes [Bug #16092]

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0