instance_of? ignores inheritance
Question
What's the output of the following Ruby 3 code?
class Example; end
example = Example.new
example.instance_of?(Object) # => ???
The correct answer is
-
true -
falseCorrect -
nil -
Object
Explanation
TL;DR
instance_of? returns true only when the receiver's class is exactly the given class. example.class is Example, not Object, so example.instance_of?(Object) returns false even though Example inherits from Object. To test against the whole ancestor chain, use is_a? (alias kind_of?).
Step by step
class Example; end
example = Example.new
example.class # => Example
example.instance_of?(Example) # => true
example.instance_of?(Object) # => false
instance_of?(Object) is essentially example.class == Object: an exact-class check. Inheritance never enters the picture.
is_a? and its alias kind_of? are the inheritance-aware checks. They return true when the argument appears anywhere in the receiver's ancestor chain, modules included:
class Example; end
example = Example.new
Example.ancestors # => [Example, Object, Kernel, BasicObject]
example.is_a?(Example) # => true
example.is_a?(Object) # => true
example.is_a?(Comparable) # => false
example.kind_of?(BasicObject) # => true
Edge cases
is_a? also matches included modules, which instance_of? never does:
1.instance_of?(Integer) # => true
1.instance_of?(Numeric) # => false
1.is_a?(Numeric) # => true
1.is_a?(Comparable) # => true (Comparable is a module)
Module#=== behaves like is_a? with the operands flipped (Numeric === 1), which is why case statements match on class hierarchies rather than exact classes. In practice, exact-class checks with instance_of? are rare and often a design smell; polymorphism or is_a? on a well-chosen ancestor usually expresses the intent better.
Share this quiz
Comments
No comments yet. Be the first.