jethroo
jethroo

Reputation: 2124

Why doesn't a ternary operator with assignment return the expected output?

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

Answers (5)

Arup Rakshit
Arup Rakshit

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 ofa`.

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

Dty
Dty

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

Óscar López
Óscar López

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

Peter Alfvin
Peter Alfvin

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

Rudy Matela
Rudy Matela

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

Related Questions