简体   繁体   中英

Ruby - unexpected behaviour when using &&

When I write the following line:

if (collection.respond_to? :each && collection.respond_to? :to_ary)

my IDE (Aptana Studio 3) gives me the following error: , unexpected tSYMBEG

however the error goes away if I add brackets:

if ((collection.respond_to? :each) && (collection.respond_to? :to_ary))

or change && to and :

if (collection.respond_to? :each and collection.respond_to? :to_ary)

Any ideas why this is happening? Also what is the difference between && and and ?

Thanks

&& has a high precedence (stronger than and , stronger than = ).

foo = 3 and 5 # sets foo = 3
foo = 3 && 5  # sets foo = true

It's also stronger than an ambiguous function call. Your code is parsed as such

 if (collection.respond_to? :each && collection.respond_to? :to_ary)
 if (collection.respond_to? (:each && collection.respond_to?) :to_ary)

which doesn't make any sense. While using and is parsed as such

 if (collection.respond_to? :each and collection.respond_to? :to_ary)
 if (collection.respond_to?(:each) and collection.respond_to?(:to_ary))

I recommend that you use this one (as it doesn't rely on operator precedence rules and uses the least braces, has shortest brace-distances, and uses and which are more often to be found in if conditions than && ):

 if collection.respond_to?(:each) and collection.respond_to?(:to_ary)

Because Ruby is a dynamic language ruby has no way of knowing if you are using the symbols as integers (in which the are stored), and thus the '&&' operator has precedens over function calls, thus you are actually calling

collection.respond_to? (:each && collection.respond_to? :to_ary) collection.respond_to? (:each && collection.respond_to? :to_ary) instead of calling

(collection.respond_to? :each) and (collection.respond_to? :to_ary)

which is to method calls then an boolean logic operator. When using 'and' instead of &&, 'and' has much lower precedens (lower than function calls) and thus it also works.

'and' and 'or' vs '&&' '||'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM