'||=' operator in Ruby

Could some one explain to me the meaning of the following Ruby code? (I saw this code snippet in one guy's project):

car ||= (method_1 || method_2 || method_3 || method_4)

What is the difference between the above code and the following code?

car = method_1 || method_2 || method_3 || method_4

----------update--------------

Ok, I got the meaning of ||= operator after read @Dave's explanation, my next question is if both method_2, method_3 and method_4 return a value, which one's value will be assigned to car? (I suppose car is nil initially)


It's an assignment operator for 'Conditional Assignment'

See here -> http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Operators

Conditional assignment:

 x = find_something() #=>nil
 x ||= "default"      #=>"default" : value of x will be replaced with "default", but only if x is nil or false
 x ||= "other"        #=>"default" : value of x is not replaced if it already is other than nil or false

Operator ||= is a shorthand form of the expression:

x = x || "default" 

EDIT:

After seeing OP's edit, the example is just an extension of this, meaning:

car = method_1 || method_2 || method_3 || method_4

Will assign the first non-nil or non-false return value of method_1, method_2, method_3, method_4 (in that order) to car or it'll retain its old value.


car ||= (method_1 || method_2) 

is equivalent to

car = (car || (method_1 || method_2)) 

In general,

x op= y 

means

x = x op y

the ||= operator checks first, if your value car is already set. If car returns nil, it will assign the first value on the right side which doesn't return nil or false.

So, given your example from above, if you assign a value to car like

car = "BMW"

and you execute you code-snippet, the value of car will still be "BMW";

If method_1 returns (for instance) the String "Value from Method 1" and car is nil or false, then car this String will be assigned to car

car = nil
car ||= (method_1 || method_2)
car # => "Value from Method 1"

If method_1 also returns nil/false, it will check for the value in method_2, and so forth, until it gets some sort of true-value

The difference to your second code-snippet is, that in case of ||= the variable car will be evaluated first, and set if it returns nil or false.

If you use =only, no evaluation will happen and car will be set to the first value on the right that doesn't return nil or false.

-- UPDATE --

To answer your update question, the value on the right side will be evaluated from left to right, so the first one that doesn't return nil or false will be assigned.

car = nil
# method_1 => "nil"
# method_2 => "false"
# method_3 => "value method 3"
# method_4 => "I won't be called"

car ||= (method_1 || method_2 || method_3 || method_4)
# => "value method 3"

car ||= (method_1 || method_2 || method_3 || method_4)  

car will retain its value after this statement is run, if car initially is not nil.

If car was nil before this statement, the first non nil value to return from method_1, method_2, ... will be assigned to car.


car = method_1 || method_2 || method_3 || method_4

In this case, car will be re-assigned the first non nil value to return out of the methods even if car already has a non nil value before this statement ran