Reputation: 2124
I'm wondering why assignment with the ternary operator reacts strangely:
a = "foo"
=> "foo"
a = nil ? nil : a
=> "foo"
a
=> "foo"
but:
a = nil ? nil : a
=> "foo"
a = "bar" ? "bar" : a
=> "bar"
a
=> "bar"
and:
if a = nil
puts "should be nil"
end
=> nil
won't puts
the string because a = nil
will return nil
thus false, although the assignment was successful.
Is that all behaving like intended?
Upvotes: 2
Views: 6682
Reputation: 118299
a = "foo"
# => "foo"
a = nil ? nil : a
# => "foo"
a
# => "foo"
To explain the above I would start with this - "Every thing in Ruby is an object except block;all object in Ruby is having a truth value,except nil
and false
." Thus in your above part of code a = nil ? nil : a
expression will be evaluated as a = a
. That's why 'foo'has been returned as a value of
a`.
a = "bar" ? "bar" : a
# => "bar"
a
# => "bar"
As I just said except nil
and false
all object has truthy value,"bar" is always true
. so the expression a = "bar" ? "bar" : a
will be evaluated as a = "bar"
.
if a = nil
puts "should be nil"
end
=> nil
The same explanation goes to the if a = nil
part as I explained above. So due to false
control doesn't get into the if
clause body,and returned nil
.
Upvotes: 1
Reputation: 12273
if a = nil
This isn't returning false, it's returning what was assigned, which in this case was nil
. nil
is 'falsy' so that's why it does not go into the puts
As to why:
a = "foo"
=> "foo"
a = nil ? nil : a
=> "foo"
a
=> "foo"
It's because you are assigning a
again. nil ? nil : a
returns a
so that's what gets assigned. So a = nil ? nil: a
ends up being interpreted like a = a
.
Upvotes: 7
Reputation: 236170
I believe this:
if a = nil
should be:
if a == nil
A single =
means assignment, and a = nil
is assigning nil
to a
and evaluating to nil
as a result, which is false. That's why the execution doesn't enter the puts
part, whereas ==
means equality testing.
Other than that, what do you find strange in the code? It's normal behavior after all.
Upvotes: 5
Reputation: 29449
Assuming you intended a = nil
to be an assignment and knew it was not a comparison, it doesn't return whether or not it is successful.
It returns the value assigned, namely nil
.
Upvotes: 2
Reputation: 6480
The example you provided is behaving as intended.
Perhaps you're confusing the assignment operator =
with the comparison operator ==
. Try the last snipped of code like this:
if a == nil
puts "should be nil"
end
=> nil
> a
=> "bar"
Upvotes: 1