-1

In the code below, if I replace the and in the any? statement with &&, it throws an error unexpected tIDENTIFIER, expecting '}'.

def ArrayAddition(arr)
  i = 2
  until i == arr.length
    combinations = arr.permutation(i).to_a
    return true if combinations.any?{|array| array.inject(&:+) == arr.max and !array.include? arr.max}
    i+=1
  end
    false
end

What is going on here? Does Ruby handle these operators differently?

sawa
  • 160,959
  • 41
  • 265
  • 366
Marc Fletcher
  • 812
  • 11
  • 33

2 Answers2

3

Yes. and has lower precedence than && (and almost everything else). This expression:

foo and bar baz

...is parsed like this:

foo and (bar baz)

...so Ruby knows foo is a method name (because it can't be anything else). On the other hand, this expression:

foo && bar baz

...is parsed like this:

(foo && bar) baz

...which just doesn't make sense and you get a syntax error.

Generally speaking you should use && unless you specifically want and's lower precedence, so in this case the easiest fix to the syntax error is to use parentheses around the method argument:

foo && bar(baz)

...and so:

array.inject(&:+) == arr.max && !array.include?(arr.max)

As a bonus, this is more readable as well.

Jordan Running
  • 97,653
  • 15
  • 175
  • 173
3

The operators and and && have different precedence, and are not equivalent. As such, the Ruby Style Guide advises against using and and or operators: The and and or keywords are banned. It's just not worth it. Always use && and || instead.

Due to the difference in precedence, the other operators in the expression have higher or lower comparative precedence. In this case, the argument for the Array#include? call end up binding to the wrong expression.

You can solve this by adding parentheses around the argument to the Array#include? call.

Michael Gaskill
  • 7,738
  • 10
  • 38
  • 42
  • 1
    If you have something constructive to add to the answer, please comment. Arbitrary anonymous downvotes do nothing to improve the quality of the answers. – Michael Gaskill May 20 '16 at 04:59
  • 2
    Upvoted to counteract whatever troll has decided to inflict themselves upon us tonight (I have a guess...), and for the style guide link. – Jordan Running May 20 '16 at 05:07
  • Thanks, @Jordan - I have no idea who it might be. I'd certainly prefer constructive feedback to improve the answer. But I guess it's easier (and maybe more satisfying) to just downvote an answer and move on... – Michael Gaskill May 20 '16 at 05:15
  • 1
    *"Always use && and || instead."* is quite harsh. `and` and `or` work great for control flow. – Stefan May 20 '16 at 06:13