Jakub Arnold
Jakub Arnold

Reputation: 87210

Difference between "and" and && in Ruby?

What is the difference between the && and and operators in Ruby?

Upvotes: 386

Views: 217365

Answers (9)

marcingo
marcingo

Reputation: 73

For me the behavior of and as opposed to modifier if is preferable if I want to exploit a side effect of the conditional expression - watch the undefined local variable or method 'y' in the first attempt:

km@latika:~$ irb
irb(main):001:0> x=y if (y="hello")
(irb):1: warning: found `= literal' in conditional, should be ==
(irb):1:in `<main>': undefined local variable or method `y' for main:Object (NameError)
        from /usr/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
        from /bin/irb:25:in `load'
        from /bin/irb:25:in `<main>'
irb(main):002:0> quit

At this point though y is already assigned, so I restart irb to demonstrate my point with a fresh start:

km@latika:~$ irb
irb(main):001:0> y="hello" and x=y
=> "hello"
irb(main):002:0> quit

In my opinion this is the nicest way to override a variable with something not nil (or false, but that is outside the point). Especially if instead of "hello" we have complicated_calculation().

Upvotes: 0

Dheeraj Maheshwari
Dheeraj Maheshwari

Reputation: 407

and checks only first condition and gives result on other hand && strongly checks both conditions and gives logical result.

Upvotes: 1

Feuda
Feuda

Reputation: 2365

and has lower precedence, mostly we use it as a control-flow modifier such as if:

next if widget = widgets.pop

becomes

widget = widgets.pop and next

For or:

raise "Not ready!" unless ready_to_rock?

becomes

ready_to_rock? or raise "Not ready!"

I prefer to use if but not and, because if is more intelligible, so I just ignore and and or.

Refer to "Using “and” and “or” in Ruby" for more information.

Upvotes: 5

Santhosh
Santhosh

Reputation: 29094

and has lower precedence than &&.

But for an unassuming user, problems might occur if it is used along with other operators whose precedence are in between, for example, the assignment operator:

def happy?() true; end
def know_it?() true; end

todo = happy? && know_it? ? "Clap your hands" : "Do Nothing"

todo
# => "Clap your hands"

todo = happy? and know_it? ? "Clap your hands" : "Do Nothing"

todo
# => true

Upvotes: 23

Dominic Rodger
Dominic Rodger

Reputation: 99751

and is the same as && but with lower precedence. They both use short-circuit evaluation.

WARNING: and even has lower precedence than = so you'll usually want to avoid and. An example when and should be used can be found in the Rails Guide under "Avoiding Double Render Errors".

Upvotes: 411

Kevin Ng
Kevin Ng

Reputation: 2174

I don't know if this is Ruby intention or if this is a bug but try this code below. This code was run on Ruby version 2.5.1 and was on a Linux system.

puts 1 > -1 and 257 < 256
# => false

puts 1 > -1 && 257 < 256
# => true

Upvotes: 0

Gabe Kopley
Gabe Kopley

Reputation: 16667

|| and && bind with the precedence that you expect from boolean operators in programming languages (&& is very strong, || is slightly less strong).

and and or have lower precedence.

For example, unlike ||, or has lower precedence than =:

> a = false || true
 => true 
> a
 => true 
> a = false or true
 => true 
> a
 => false

Likewise, unlike &&, and also has lower precedence than =:

> a = true && false
 => false 
> a
 => false 
> a = true and false
 => false 
> a
 => true 

What's more, unlike && and ||, and and or bind with equal precedence:

> !puts(1) || !puts(2) && !puts(3)
1
 => true
> !puts(1) or !puts(2) and !puts(3)
1
3
 => true 
> !puts(1) or (!puts(2) and !puts(3))
1
 => true

The weakly-binding and and or may be useful for control-flow purposes: see http://devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby/ .

Upvotes: 43

Andrew Grimm
Andrew Grimm

Reputation: 81450

The Ruby Style Guide says it better than I could:

Use &&/|| for boolean expressions, and/or for control flow. (Rule of thumb: If you have to use outer parentheses, you are using the wrong operators.)

# boolean expression
if some_condition && some_other_condition
  do_something
end

# control flow
document.saved? or document.save!

Upvotes: 69

tadman
tadman

Reputation: 211560

The practical difference is binding strength, which can lead to peculiar behavior if you're not prepared for it:

foo = :foo
bar = nil

a = foo and bar
# => nil
a
# => :foo

a = foo && bar
# => nil
a
# => nil

a = (foo and bar)
# => nil
a
# => nil

(a = foo) && bar
# => nil
a
# => :foo

The same thing works for || and or.

Upvotes: 262

Related Questions