Project

General

Profile

Bug #16092 ยป modifier-statements.patch

Dan0042 (Daniel DeLorme), 08/09/2019 06:45 PM

View differences:

doc/keywords.rdoc (working copy)
expressions}[rdoc-ref:syntax/control_expressions.rdoc]
if::
Used for +if+ and modifier +if+ expressions. See {control
Used for +if+ and modifier +if+ statements. See {control
expressions}[rdoc-ref:syntax/control_expressions.rdoc]
in::
......
See {modules and classes}[rdoc-ref:syntax/modules_and_classes.rdoc]
unless::
Used for +unless+ and modifier +unless+ expressions. See {control
Used for +unless+ and modifier +unless+ statements. See {control
expressions}[rdoc-ref:syntax/control_expressions.rdoc]
until::
doc/syntax/control_expressions.rdoc (working copy)
== Modifier +if+ and +unless+
+if+ and +unless+ can also be used to modify an expression. When used as a
modifier the left-hand side is the "then" expression and the right-hand side
modifier the left-hand side is the "then" statement and the right-hand side
is the "test" expression:
a = 0
......
This will print 0.
While the modifier and standard versions have both a "test" expression and a
"then" expression, they are not exact transformations of each other due to
"then" statement, they are not exact transformations of each other due to
parse order. Here is an example that shows the difference:
p a if a = 0.zero?
......
of a +rescue+ block. See {Exceptions}[rdoc-ref:syntax/exceptions.rdoc]
for proper usage of +retry+.
== Modifier Statements
When used as a modifier, +if+, +else+, +while+, +until+ and +rescue+ become
statements, not expressions. This means they cannot be used in contexts where
an expression is expected, such as method arguments. Wrap with parentheses
to create an expression.
puts( 1 if true ) #=> SyntaxError
puts((1 if true)) #=> 1
puts (1 if true) #=> 1, because of optional parentheses for method
puts( 1 rescue true ) #=> SyntaxError
puts((1 rescue true)) #=> 1
puts (1 rescue true) #=> 1, because of optional parentheses for method
The right-hand side of a modifier statement is also one of those contexts
where an expression is expected. So in <code>a if b rescue c</code>, because
<code>b rescue c</code> is a statement and therefore not allowed as the
condition of the +if+ statement, the code is necessarily parsed as <code>(a
if b) rescue c</code>.
This interacts with operator precedence in such a way that:
stmt if v = expr rescue x
stmt if v = expr unless x
are parsed as:
stmt if v = (expr rescue x)
(stmt if v = expr) unless x
== Flip-Flop
The flip-flop is a rarely seen conditional expression. It's primary use is
doc/syntax/precedence.rdoc (working copy)
<code>-1</code> or <code>-(a + b)</code>.
Modifier-if, modifier-unless, etc. are for the modifier versions of those
keywords. For example, this is a modifier-unless expression:
keywords. For example, this is a modifier-unless statement:
a += 1 unless a.zero?
Note that <code>(a if b rescue c)</code> is parsed as <code>((a if b) rescue
c)</code> regardless of precedence. See {modifier
statements}[control_expressions_rdoc.html#label-Modifier+Statements].
<code>{ ... }</code> blocks have priority below all listed operations, but
<code>do ... end</code> blocks have lower priority.
    (1-1/1)