Ruby `&&` vs `and` in a block [duplicate] - ruby

This question already has answers here:
Difference between "and" and && in Ruby?
(8 answers)
Closed 6 years ago.
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?

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.

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.

Related

Precedence of and/or versus method arguments in ruby

Here are two tests:
if [1,2,3,4].include? 2 && nil.nil?
puts :hello
end
#=>
and
if [1,2,3,4].include?(2) && nil.nil?
puts :hello
end
#=> hello
The above tells me that && has higher precedence than method arguments so it logically ands 2 && nil.nil? which is true and passes that as an argument to include?.
However, there is this test:
if [1,2,3,4].include? 2 and nil.nil?
puts :hello
end
#=> hello
So this is telling me that method arguments and 'and' have the same precedence (or method args are higher than 'and') since it passed 2 to include? before it processed 'and'.
Note: I understand that && and and have different precedence. The question is not regarding this but regarding and or or vs the arguments to a ruby method.
I can't find documentation that affirms this. For instances, this doesn't mention method arguments at all: http://phrogz.net/programmingruby/language.html#table_18.4 or http://romhack.wikia.com/wiki/Ruby_operators.
Could anyone explain this behavior? Namely in that how does ruby know to pass values as arguments to a method vs. process operators?
As you said && and and have different precedence, however the explanation for the following example:
if [1,2,3,4].include? 2 and nil.nil?
puts :hello
end
#=> hello
is the binding strenght of the and as you can read here:
Difference between "and" and && in Ruby?
This basically explains that 2 and nil.nil? will be evaluated as nil, however it will return 2 as can be seen in this example:
foo = :foo
bar = nil
a = foo and bar
# => nil
a
# => :foo
a = foo && bar
# => nil
a
# => nil
I've never seen any documentation about method argument precedence, but one rule of thumb I use when seeing method arguments is to mentally strip the whitespace wherever possible in the arguments and still have the same expression. This normally gives me the precedence:
[1,2,3,4].include? 2&&nil.nil? is the same expression, but you cannot strip the whitespace in
[1,2,3,4].include? 2 and nil.nil? and therefore, the precedence is left to right ... I.e. Method argument is 2.
Anyway, the better question is why on earth would you write statements like this?
Omitting method parenthesis is only useful for code readability. However, your statements are hardly readable and makes one pause over the code and think about it more than he should. If I was to review code like this, I would definitely fail the code review due to poor readability.
In fact, many style guides explicitly state that most methods with arguments should be parenthesized (is this even a word ;). For example:
Ruby style guide

Does ruby need ternary operator at all?

I made a small test today:
> false && 1 || 2
> 2
> true && 1 || 2
> 1
So if we could already do with binary operators, why did we need a ternary ?
> false ? 1 : 2
> 2
> true ? 1 : 2
> 1
As it is not simply an alias and complicates parsing.
To deal with the specific case in your question…
What if 1 was different value, one that evaluated as false?
And in general:
No. You can always replace a ternary operator with an if/else construct. That isn't as convenient though.
No language needs a ternary operator.
The ternary operator is a well-known language construct. IMO people generally expect it in script-ish(-looking) languages, so there it is. I don't see a huge reason to not have it.
The conditional operator is needed in languages like C, because if/else is a statement, it doesn't evaluate to a return value. But in Ruby, everything is an expression, everything has a return value, there are no statements.
Therefore, you can always replace the conditional operator with a conditional expression:
foo = bar ? baz : qux
is exactly equivalent to
foo = if bar then baz else qux end
In C, you cannot write this, you'd have to write
if bar then foo = baz else foo = aux end
leading to code duplication. That's why you need the conditional operator in C. In Ruby, it is unnecessary.
Actually, since Ruby is an object-oriented language, all conditionals are unnecessary. You can just use polymorphism instead.

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)
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 '&&' '||'

What does the "===" operator do in Ruby? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
=== vs. == in Ruby
I've seen it used a few times lately but can't figure out what it does. Can anyone illustrate how it works?
Just like with every other method in Ruby (or actually pretty much any object-oriented language),
a === b
means whatever the author of a's class wants it to mean.
However, if you don't want to confuse the heck out of your colleagues, the convention is that === is the case subsumption operator. Basically, it's a boolean operator which asks the question "If I have a drawer labelled a would it make sense to put b in that drawer?"
An alternative formulation is "If a described a set, would b be a member of that set?"
For example:
(1..5) === 3 # => true
(1..5) === 6 # => false
Integer === 42 # => true
Integer === 'fourtytwo' # => false
/ell/ === 'Hello' # => true
/ell/ === 'Foobar' # => false
The main usage for the === operator is in case expressions, since
case foo
when bar
baz
when quux
flurb
else
blarf
end
gets translated to something (roughly) like
_temp = foo
if bar === _temp
baz
elsif quux === _temp
flurb
else
blarf
end
Note that if you want to search for this operator, it is usually called the triple equals operator or threequals operator or case equality operator. I really dislike those names, because this operator has absolutely nothing whatsoever to do with equality.
In particular, one would expect equality to be symmetric: if a is equal to b, then b better be also equal to a. Also, one would expect equality to be transitive: if a == b and b == c, then a == c. While there is no way to actually guarantee that in a single-dispatch language like Ruby, you should at least make an effort to preserve this property (for example, by following the coerce protocol).
However, for === there is no expectation of either symmetry or transitivity. In fact, it is very much by design not symmetric. That's why I don't like calling it anything that even remotely resembles equality. It's also why I think, it should have been called something else like ~~~ or whatever.
Thanks for your edit Jacob, I was about to call you out ;) I'll post a couple of examples anyway. The implementation of === differs depending on type. For example:
(1...3) === 2
=> true
/test/ === "this is a test"
=> true
case 'test'
when /blah/
"Blach"
when /test/
"Test"
else
"Fail"
end
=> "Test"
Stephen, checkout http://ruby-doc.org/docs/ProgrammingRuby/ (the "Pickaxe"), it should be able to help you out with questions such as this in the future.
In Ruby, the === operator is used to test equality within a when clause of a case statement. In other languages, the above is true.
To my knowledge, Ruby doesn't have true operators, they are all methods which are invoked on the LHS of the expression, passing in the RHS of the expression.
So, really, you could override any "operator" you want in your classes to perform whatever the heck you want (analogous to operator overloading in C++).

Difference between "or" and || in Ruby? [duplicate]

This question already has answers here:
Difference between "and" and && in Ruby?
(8 answers)
Closed 3 years ago.
What's the difference between the or and || operators in Ruby? Or is it just preference?
It's a matter of operator precedence.
|| has a higher precedence than or.
So, in between the two you have other operators including ternary (? :) and assignment (=) so which one you choose can affect the outcome of statements.
Here's a ruby operator precedence table.
See this question for another example using and/&&.
Also, be aware of some nasty things that could happen:
a = false || true #=> true
a #=> true
a = false or true #=> true
a #=> false
Both of the previous two statements evaluate to true, but the second sets a to false since = precedence is lower than || but higher than or.
As the others have already explained, the only difference is the precedence. However, I would like to point out that there are actually two differences between the two:
and, or and not have much lower precedence than &&, || and !
and and or have the same precedence, while && has higher precedence than ||
In general, it is good style to avoid the use of and, or and not and use &&, || and ! instead. (The Rails core developers, for example, reject patches which use the keyword forms instead of the operator forms.)
The reason why they exist at all, is not for boolean formulae but for control flow. They made their way into Ruby via Perl's well-known do_this or do_that idiom, where do_this returns false or nil if there is an error and only then is do_that executed instead. (Analogous, there is also the do_this and then_do_that idiom.)
Examples:
download_file_via_fast_connection or download_via_slow_connection
download_latest_currency_rates and store_them_in_the_cache
Sometimes, this can make control flow a little bit more fluent than using if or unless.
It's easy to see why in this case the operators have the "wrong" (i.e. identical) precedence: they never show up together in the same expression anyway. And when they do show up together, you generally want them to be evaluated simply left-to-right.
and/or are for control flow.
Ruby will not allow this as valid syntax:
false || raise "Error"
However this is valid:
false or raise "Error"
You can make the first work, with () but using or is the correct method.
false || (raise "Error")
puts false or true --> prints: false
puts false || true --> prints: true
The way I use these operators:
||, && are for boolean logic. or, and are for control flow. E.g.
do_smth if may_be || may_be -- we evaluate the condition here
do_smth or do_smth_else -- we define the workflow, which is equivalent to
do_smth_else unless do_smth
to give a simple example:
> puts "a" && "b"
b
> puts 'a' and 'b'
a
A well-known idiom in Rails is render and return. It's a shortcut for saying return if render, while render && return won't work. See "Avoiding Double Render Errors" in the Rails documentation for more information.
or is NOT the same as ||. Use only || operator instead of the or operator.
Here are some reasons. The:
or operator has a lower precedence than ||.
or has a lower precedence than the = assignment operator.
and and or have the same precedence, while && has a higher precedence than ||.
Both or and || evaluate to true if either operand is true. They evaluate their second operand only if the first is false.
As with and, the only difference between or and || is their precedence.
Just to make life interesting, and and or have the same precedence, while && has a higher precedence than ||.
Just to add to mopoke's answer, it's also a matter of semantics. or is considered to be a good practice because it reads much better than ||.

Resources