Reviewing some Ruby code recently I came across an operator I hadn’t seen before: `&&=`

. I guessed intuitively what it meant, judging from context and experience, but my Google-fu wasn’t up to the task of confirming my suspicions. I fired up irb and had away with it:

> a = true

=> true

> a &&= false

=> false

> a &&= true

=> false

`a &&= b`

is a shorthand notation for `a = a && b`

. Or rather, if both `a`

and `b`

are true then a will be true, otherwise a will be set to false. `&&=`

(and-equals) is, of course the sibling of `||=`

(or-equals), which we see a great deal more of in Ruby development. As before:

> a = true

=> true

> a ||= false

=> true

> a = false

=> false

> a ||= true

=> true

> a ||= false

=> true

`||=`

returns true if either of the operands yield true. In Ruby only nil and false are false, everything else is true.

> a = 1

=> 1

> a &&= 0

=> 0

> a = false

=> false

> a &&= 0

=> false

> a = true

=> true

> a &&= 0

=> 0

> a = false

=> false

> a ||= 0

=> 0

It’s important to distinguish the `&&=`

and `||=`

operators from the `&=`

and `|=`

operators. The prior, as discussed above are boolean operators, which assign a true or false value to the left operand based on their operation. The latter, on the other hand, are set operations that operate on enumerable objects such as Arrays and Sets. `&=`

is the intersection operator and `|=`

is the union operator. Here are some examples:

> a = [1,2]

=> [1, 2]

> b = [2,3]

=> [2, 3]

> a &= b

=> [2]

So here we get the intersection, or an array containing only values that are in both arrays. This is shorthand notation for `a = a & b`

. Here’s the union operator at work:

> a = [1,2]

=> [1, 2]

> b = [2,3]

=> [2, 3]

> a |= b

=> [1, 2, 3]

It grabs all values from both arrays, removing duplicates. There are also the + and – operators for enumerables, concatenation and difference respectively:

> a = [2,1]

=> [2, 1]

> b = [3,2]

=> [3, 2]

> a +=b

=> [2, 1, 3, 2]

> a = [2,1]

=> [2, 1]

> b = [3,2]

=> [3, 2]

> a -= b

=> [1]

A Set sorts and removes duplicates, so in that case the concatenation (`+=`

) and union (`&=`

) operators are equivalent:

> require 'set'

=> true

> a = Set.new([2,1])

=> #<Set: {1, 2}>

> b = Set.new(2,3])

=> #<Set: {2, 3}>

> a += b

=> #<Set: {1, 2, 3}>