LaunchKit
All quizzes
Ruby 0 views

!! is two calls to BasicObject#!

Question

What is the return value of the following Ruby code?

(42 + 0.42).!@.!@ # => ???

The correct answer is

Explanation

TL;DR

.!@ is method-call syntax for the unary ! operator, so (42 + 0.42).!@.!@ is just !!(42 + 0.42). 42 + 0.42 is 42.42, a truthy value; one negation gives false, the second gives true.

Step by step

42 + 0.42         # => 42.42
(42 + 0.42).!@    # => false
(42 + 0.42).!@.!@ # => true

The double negation idiom

!! converts any value to its boolean equivalent: false for nil and false, true for everything else:

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

!! is not an operator of its own; it is two ordinary negations applied in sequence.

! is a method

Unary ! is a regular method, BasicObject#!:

42.method(:!).owner # => BasicObject

42.!  # => false
42.!@ # => false
!42   # => false

The @ suffix is the convention Ruby uses to name unary operator methods. It matters for operators that also exist in binary form: -@ (unary minus) versus - (subtraction), +@ versus +. ! has no binary form, so the method's actual name is plain :!, but the parser still accepts .!@ as call syntax.

Because ! is a method, it can be overridden, and the operator honors the override:

class Falsey
  def !
    true
  end
end

!Falsey.new # => true

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.