开发者

Double Pipe Symbols in Ruby Variable Assignment? [duplicate]

This question already has answers here: 开发者_开发百科 Closed 12 years ago.

Possible Duplicate:

What does ||= mean in Ruby?

Forgive me if this is a newbie question but I'm reading a book on rails where the writer used this expression in a helper method:

@current_user ||= User.find_by_id(session[:user_id])

Is this use of double pipes still a Boolean OR statement?

If so how does it work?


It's a conditional assignment. From here:

 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


The code foo ||= bar is almost equivalent to foo = foo || bar. In Ruby (as in many languages, like JavaScript or Io) boolean operators are "guard" operators. Instead of always returning true or false, they evaluate to the value of the first operand that evaluates to a "truthy" value.

For example, this code foo = 1 || delete_all_files_from_my_computer() will not delete anything: foo will be set to 1 and the second operand won't even be evaluated.

In Ruby, the only "non-truthy" values are nil and false. So the code foo ||= bar will only evaluate bar and set foo to the result if foo is nil or false.

As instance variables default to nil when not set, code like @foo ||= bar is a common Ruby idiom to set the instance variable if it has not already been set.


You can think of it as short for:

@current_user = @current_user || User.find_by_id(session[:user_id])

@current_user gets evaluated first, if it is non-null then the OR short-circuits, returning the value of @current_user, and not calling User.find_by_id.

(This works only because Ruby treats null as false, and non-null as true, in a boolean context. It doesn't work for languages like Java that don't treat non-booleans as truthy.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜