Boolean operators and Set operations

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}>

Tags: ,

2 Responses to “Boolean operators and Set operations”

  1. Sarah Allen says:

    I use ||= all the time to set a variable only if it hasn’t already been initialized. I’ve never used &&=, what is a typical use case for that operator?

    Thanks,
    Sarah

  2. rtfletch says:

    I guess I should have discussed that. I haven’t seen too many situations where I would prefer to use &&=, but one example is when you have a number of operations you want to execute conditionally on the previous one finishing. For example:

    @a = do_this
    @a &&= do_that
    @a &&= do_something_else

    do_that won’t execute if do_this returns false or nil. And so on down the line. This might arguably be made a little more clear by some chain of if-else blocks, such as:

    if do_this && do_that
    do_something_else
    end

Leave a Reply

You must be logged in to post a comment.