Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between '&&' and '&' in Ruby

Tags:

ruby

Recently, I observed a very interesting result in Ruby while making use of && and & for the input combination of 0 & 1.

Can someone please explain the below output with respect to the above mentioned two operators? The below is implemented using Ruby 2.0.0-p451

2.0.0-p451 :006 > 0 && 1
 => 1 


2.0.0-p451 :008 > 0 & 1
 => 0 

Thank you

like image 353
boddhisattva Avatar asked Nov 29 '22 15:11

boddhisattva


2 Answers

&& is the logical AND operator. It will be truthy, IFF both operands are truthy. And it is lazy (aka short-circuiting), which means it will stop evaluating as soon as the result has been fully determined. (So, since both operands need to be truthy, if the first operand is falsy, you already know that the result is going to be falsy, without even evaluating the second operand.) It will also not just return true or false, but rather return the operand which determines the outcome. IOW: if a is falsy, it'll return a, otherwise it'll return b:

nil && (loop {})
# => nil
# Note: the infinite loop is *not* evaluated
# Note: the return value is nil, not false

true && nil
# => nil

true && 'Hello'
# => 'Hello'

& simply calls the method &. It will do whatever the object wants it to do:

def (weirdo = Object.new).&(other)
  puts 'Whoah, weird!'
  'Hello, ' + other
end

weirdo & 'World'
# Whoah, weird!
# => 'Hello, World'

In general, & and its brother | are expected to perform conjunction and disjunction. So, for booleans, they are perform AND and OR (TrueClass#&, FalseClass#&, NilClass#&, TrueClass#|, FalseClass#|, NilClass#|) with the exception that & and | are standard method calls and thus always evaluate their argument and that they always return true or false and not their arguments.

For Sets, they perform set intersection and set union: Set#&, Set#|. For other collections (specifically Arrays), they also perform set operations: Array#&, Array#|.

For Integers, they perform BITWISE-AND of the two-complement's binary representation: Fixnum#&, Bignum#&, Fixnum#|, Bignum#|.

like image 141
Jörg W Mittag Avatar answered Dec 23 '22 10:12

Jörg W Mittag


&& is a boolean and. It returns the second argument if the first argument is true-ish. Because 0 is true-ish in Ruby, 1 is returned.

& is a bitwise and. It compares the bit representation of the values. Because (imaging 8 bit) 00000000 (0) and 00000001 (1) have no 1 digits in common, 00000000 (0) is returned.

like image 25
spickermann Avatar answered Dec 23 '22 09:12

spickermann