Bug #16092 ยป modifier-statements.patch
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.
|
||