There is a difference. It's a subtle but important one. An expression is a type of statement. All expressions are statements but not all statements are expressions.
Most notably, statements that are not expressions include:
stmt if expr
stmt unless expr
stmt while expr
stmt until expr
stmt rescue expr
var = method expr
x,y = expr
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 a if b rescue c
, because
b rescue c
is a statement and therefore not allowed as the
condition of the if
statement, the code is necessarily parsed as (a if b) rescue c
.
This interacts with operator precedence in such a way that:
stmt if v = expr rescue x
stmt if expr rescue x
stmt if v = expr unless x
stmt if expr unless x
are parsed as:
stmt if v = (expr rescue x)
(stmt if expr) rescue x
(stmt if v = expr) unless x
(stmt if expr) unless x