On 10.01.2009 04:43, Kedar M. wrote:
I certainly appreciate your attempts to make me get it. I think I am
close. The only weird thing is I was not sure whether
“surprising” if (1+1 != 2)
is an “expression” and if yes, what its value was. I thought that this
expression is same as (“surprising” if (1+1 != 2)) and both should
evaluate to the same value.
They are the same and they do evaluate to the same value. However,
the point which probably hasn’t become clear so far is this: the
assignment is part of the expression that’s conditionally evaluated. If
the expression isn’t evaluated, no assignment happens.
x = 0
(x = 1) if false
x = 1 if false # same as above
In this case the assignment with 1 is never executed and hence the value
of the variable does not change. The result of the whole expression
however is either nil (in case of the condition evaluating to false) or
the result of evaluating the expression before the “if”.
Assignments happen to be defined as expressions in Ruby (everything is -
there is no distinction between statement and expression like in some
other languages). So they have a result like evaluating any other
expression like (1 + 3) for example. The way it is defined the result
of an assignment expression is the right hand side. You can view the
change of the variable as a side effect of evaluating the assignment
expression.
That’s also the reason why you can do assignment chains like
a = b = c = 0
Assignments are evaluated right to left (as opposed to 1 + 2 + 3 for
example which is evaluated left to right). The result of “c = 0” is a)
c now points to object 0 and b) 0 is also returned as result of
evaluating this, so in the end you get
(a = (b = (c = 0)))
Thus, whereas now I get that the value of (“surprising” if (1+1 != 2))
is nil, it is not clear to me if
- “surprising” if (1+1 != 2) is an expression and evaluates to some/same
value.
Yes, it is an expression and evaluates the way I have tried to outline
above. Everything is an expression in Ruby, even a case statement which
comes in handy from time to time:
foo = case x
when String
“it’s a String”
when Fixnum, Integer, Float
“it’s a number”
else
“I have no idea”
end
puts foo
A final remark, if your aim is to assign nil in case the condition is
false, the ternary operator is probably a better choice:
s = (1+1 != 2) ? “surprising” : nil
s = 1+1 != 2 ? “surprising” : nil
s = 1+1 == 2 ? nil : “surprising”
You can as well use if else which is more verbose
s = if (1+1 != 2) then “surprising” else nil end
The main point is to make the assignment unconditional.
Apologies if this is becoming rather lengthy.
No worries. That’s ok.
Kind regards
robert