LaunchKit
All quizzes
Ruby 0 views

1.0 == 1 versus eql? and equal?

Question

What is the return value of the following Ruby code?

1.0.eql?(1)   # => false
1.0.equal?(1) # => false

1.0 == 1      # => ???

The correct answer is

Explanation

TL;DR

Ruby ships three distinct equality checks. == compares numeric values across types, so 1.0 == 1 returns true. eql? requires the same value and the same class, and equal? requires the very same object, which is why both return false for a Float and an Integer.

==: value equality

Numeric classes implement == with type conversion: an Integer and a Float are equal when they represent the same mathematical value.

1.0 == 1   # => true
1 == 1.0   # => true

eql?: value plus class

Float#eql? returns true only when the argument is also a Float with the same value. No numeric conversion happens.

1.0.eql?(1)   # => false
1.eql?(1.0)   # => false
1.0.eql?(1.0) # => true

This is the method Hash uses (together with #hash) to compare keys, so a Float key and an Integer key never collide:

h = { 1.0 => :float, 1 => :int }

h[1]   # => :int
h[1.0] # => :float

equal?: object identity

equal? returns true only when both operands are the exact same object. 1.0 and 1 are different objects, so it returns false. Never override this method.

1.0.equal?(1) # => false

Edge cases

On 64-bit platforms small floats are flonums, immediate values encoded directly in the reference, just like small integers. Two occurrences of the same flonum are therefore the same object:

1.0.equal?(1.0) # => true

Do not rely on this for identity checks; it is an encoding detail, and larger floats are heap-allocated objects with distinct identities.

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.