LaunchKit
All quizzes
Ruby 0 views

!(!!!()) and the value of empty parentheses

Question

What's the return value of the following Ruby code?

var = !(!!!())

var # => ???

The correct answer is

Explanation

TL;DR

Empty parentheses are a valid expression in Ruby and evaluate to nil. The expression then applies ! four times: nil is falsy, so each negation flips the boolean. nil becomes true, false, true, and finally false. var is false.

Step by step

()        # => nil
!()       # => true
!!!()     # => true
!(!!!())  # => false

Reading inside out:

  1. () evaluates to nil.
  2. !() negates nil. nil is falsy, so the result is true.
  3. !!() negates that: false. !!!() negates again: true.
  4. The outer !(...) negates true, so the whole expression is false, and the assignment returns it.

Only nil and false are falsy in Ruby, which is why the first ! turns nil into a proper boolean and every later ! just alternates it.

Under the hood

The compiled instructions make the structure obvious, one putnil followed by four negations:

puts RubyVM::InstructionSequence.compile("!(!!!())").disasm

Output (the == disasm header line is trimmed):

0000 putnil                                                           (   1)[Li]
0001 opt_not                                <calldata!mid:!, argc:0, ARGS_SIMPLE>[CcCr]
0003 opt_not                                <calldata!mid:!, argc:0, ARGS_SIMPLE>[CcCr]
0005 opt_not                                <calldata!mid:!, argc:0, ARGS_SIMPLE>[CcCr]
0007 opt_not                                <calldata!mid:!, argc:0, ARGS_SIMPLE>[CcCr]
0009 leave

Each opt_not is an optimized call to the ! method (mid:! in the calldata). ! is a real method, defined on BasicObject, so a class can override it, and the VM falls back to a regular method call when that happens.

Edge cases

The useful relative of this puzzle is the double bang, the standard idiom for coercing any value to a strict boolean:

!!nil    # => false
!!0      # => true
!!"abc"  # => true

One ! gives the negated boolean; two give the value's truthiness as true or false.

Share this quiz

Comments

No comments yet. Be the first.

Only used to confirm and publish your comment. Never shown publicly, never shared.

Markdown: **bold**, `code`, ```fenced blocks```, > quotes, [links](url). HTML and images are not rendered.