ChatGPT解决这个技术问题 Extra ChatGPT

Difference between "and" and && in Ruby?

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


t
the Tin Man

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


It would be a good idea to specify that one should usually use &&, while and should be used for very specific cases only.
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.)
Combine this answer with the details of tadman's answer and you get the whole picture.
Avdi updated his take on when to use and vs. &&. Basically use 'and' and 'or' for control flow because of their lower precedence. devblog.avdi.org/2014/08/26/…
A
Andrew Marshall

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.


a = foo and bar and (a = foo ) && bar proves that and has lower precedence than &&.
i don't get it: what is "foo and bar" meant to return?
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.
A
Andrew Grimm

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!

Actually the guide now says 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 anyway (e.g. document.save! unless document.saved?)
@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 by Bozhidar Batsov.
@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.
G
Gabe Kopley

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


"unlike ||, or has lower precedence than =" ...now it makes more sense, thanks!
t
the Tin Man

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

Thank you, but how is the precedence of "and" different from "&&"?
@BKSpurgeon See here for a ordered list of operator precedence in Ruby.
t
the Tin Man

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.


K
Kevin Ng

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

@JakubArnold Sarcasm is never helpful. Examples sometimes are.
@BobRodes It wasn't a sarcasm. There are 7 answers, 6 of which already have examples.
@JakubArnold I still found this example helpful.
I'm getting odd results as well. v1 = true and false p v1 # => app.rb: true, IRB: false v2 = true && false p v2 # => app.rb: false, IRB: false puts 1 > -1 && 257 < 256 # => app.rb: false, IRB: false
D
Dheeraj Maheshwari

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