371

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

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
Jakub Arnold
  • 85,596
  • 89
  • 230
  • 327

8 Answers8

396

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".

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
  • 61
    It would be a good idea to specify that one should usually use `&&`, while `and` should be used for very specific cases only. – Marc-André Lafortune Apr 09 '12 at 03:05
  • 13
    Another good explanation here: http://devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby/. – Andrew Marshall May 18 '12 at 05:58
  • 21
    From Andrew Marshall's link: "Another way of thinking about `and` is as a reversed `if` statement modifier: `next if widget = widgets.pop` becomes `widget = widgets.pop and next`. That's a great way of putting it, really made it "click" in my head. (And `or` is like a reversed `unless` modifier.) – GMA Oct 29 '13 at 07:31
  • 1
    Combine this answer with the details of tadman's answer and you get the whole picture. – sargas Apr 30 '14 at 22:14
  • 5
    Avdi updated his take on when to use and vs. &&. Basically use 'and' and 'or' for control flow because of their lower precedence. http://devblog.avdi.org/2014/08/26/how-to-use-rubys-english-andor-operators-without-going-nuts/ – EricC Nov 06 '14 at 21:53
  • 1
    because of the lower precedence, evaluations such as `x = true and false` makes x equal to true and `x = false or true` makes x equal to false – Eiiki Jul 08 '15 at 21:56
  • 1
    Updated link from Avdi: https://avdi.codes/how-to-use-rubys-english-andor-operators-without-going-nuts/ – Mark Robinson Jul 21 '20 at 11:44
259

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.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
tadman
  • 208,517
  • 23
  • 234
  • 262
  • 2
    `a = foo and bar` _and_ `(a = foo ) && bar` proves that `and` has lower precedence than `&&`. – sargas Apr 30 '14 at 22:15
  • i don't get it: what is "foo and bar" meant to return? – BenKoshy Apr 26 '16 at 06:08
  • `a = foo and bar` is equivalent to `(a = :foo) and nil`. Since the assignment returns a logically true value (`:foo`) then the second part evaluates, which fails, returning `nil`. – tadman Apr 26 '16 at 07:31
65

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!
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
  • 57
    Actually the [**guide now says**](https://github.com/bbatsov/ruby-style-guide/commit/5920497452c1f6f604742a735f5684e86d4c0003) to avoid `and`/`or` completely, and they might have a point. Often their usage in control flow [could be more obviously written with `if`/`unless` operators](http://devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby/) anyway (e.g. `document.save! unless document.saved?`) – Yarin Sep 14 '13 at 12:08
  • 1
    @akostadinov in case you weren't trolling: the Ruby Style guide isn't written by the creators of Ruby. Ruby was created by Yukihiro Matsumoto and others, while the Ruby Style Guide was [mainly](https://github.com/bbatsov/ruby-style-guide/graphs/contributors) by Bozhidar Batsov. – Andrew Grimm Jul 03 '14 at 23:03
  • 2
    @AndrewGrimm, thanks, good to know. Sorry for trolling but I'm sincerely confused with some aspects of ruby reality. One thing is sure - every ruby project needs strict style policies to keep the codebase maintainable. – akostadinov Jul 04 '14 at 07:59
41

|| 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/ .

Gabe Kopley
  • 16,281
  • 5
  • 47
  • 60
22

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
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Santhosh
  • 28,097
  • 9
  • 82
  • 87
  • 1
    Thank you, but how is the precedence of "and" different from "&&"? – BenKoshy May 14 '16 at 09:10
  • 3
    @BKSpurgeon See [here](https://ruby-doc.org/core-2.4.1/doc/syntax/precedence_rdoc.html) for a ordered list of operator precedence in Ruby. – thutt Jul 27 '17 at 08:25
5

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.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Feuda
  • 2,335
  • 30
  • 28
1

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

0

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
Kevin Ng
  • 2,146
  • 1
  • 13
  • 18