开发者

Why || and or behaves differently in rails? [duplicate]

开发者 https://www.devze.com 2023-01-19 17:23 出处:网络
This question already has answers here: 开发者_开发问答 Closed 12 years ago. Possible Duplicates:
This question already has answers here: 开发者_开发问答 Closed 12 years ago.

Possible Duplicates:

i = true and false in Ruby is true?

What is the difference between Perl's ( or, and ) and ( ||, && ) short-circuit operators?

Ruby: difference between || and 'or'

Is || same as or in Rails?

Case A:

 @year = params[:year] || Time.now.year
 Events.all(:conditions => ['year = ?', @year])

will produce the following SQL in script/console:

 SELECT * FROM `events` WHERE (year = 2000)

Case B:

 @year = params[:year] or Time.now.year
 Events.all(:conditions => ['year = ?', @year])

will produce the following SQL in script/console:

 SELECT * FROM `events` WHERE (year = NULL)


The reason that || and or behave differently is because of operator precedence.

Both || and && have higher precedence than the assignment operator and the assignment operator (=) has higher precedence than and/or

So your expressions will actually be evaluated as follows :-

@year = params[:year] || Time.now.year

is evaluated as

@year = ( params[:year] || Time.now.year )

and

@year = params[:year] or Time.now.year

is evaluated as

( @year = params[:year] ) or Time.now.year

If in doubt about precedence rules then use parentheses to make your meaning clear.


Quote from http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Operators:

The binary "or" operator will return the logical disjunction of its two operands. It is the same as "||" but with a lower precedence.

a = nil
b = "foo"
c = a || b  # c is set to "foo" its the same as saying c = (a || b)
c = a or b  # c is set to nil   its the same as saying (c = a) || b which is not what you want.

So you or works as:

(@year = params[:year]) or Time.now.year

So params[:year] is assigned to @year, and second part of expression is not assigned to anything. You should use explicit brackets if you want to use or:

@year = (params[:year] or Time.now.year)

And this is the difference.

0

精彩评论

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