Reputation: 229461
What is the difference? When should I use which? Why are there so many of them?
Upvotes: 574
Views: 248737
Reputation: 1
https://stackoverflow.com/a/3893305/10392483 is a great explanation ... to add some more colour to this, I tend to use is_a?
for "primatives" (String, Array, maybe Hash, etc.)
So "hello".is_a?(String)
, [].is_a?(Array)
, {}.is_a?(Hash)
For anything else, I tend to use instance_of? (Animal.new.instance_of?(Animal)
I say tend to because it's not quite that clear cut. Take for example:
class Animal;end
class Dog < Animal;end
x = Dog.new
x.is_a?(Dog) # => true
x.is_a?(Animal) # => true
x.instance_of?(Dog) # => true
x.instance_of?(Animal) # => false
As you can see, x is both a Dog and an Animal, but it's only an instance of Dog.
I see it as a question of specificity:
Animal
and not a Plant
I'll use is_a?
Dog
and not a Cat
I'll use instance_of?
You can then take this further. If I care that it's a Sighthound
and not a Bloodhound
, assuming both are subclasses of Dog
. Then I may want to make it even more specific.
That said, is_a?(Animal|Dog|Sighthound)
will always work. But if you care about the specific subclass, instance_of?
is always more specific.
Upvotes: 0
Reputation: 370357
kind_of?
and is_a?
are synonymous.
instance_of?
is different from the other two in that it only returns true
if the object is an instance of that exact class, not a subclass.
Example:
"hello".is_a? Object
and "hello".kind_of? Object
return true
because "hello"
is a String
and String
is a subclass of Object
."hello".instance_of? Object
returns false
.Upvotes: 731
Reputation: 313
It is more Ruby-like to ask objects whether they respond to a method you need or not, using respond_to?
. This allows both minimal interface and implementation unaware programming.
It is not always applicable of course, thus there is still a possibility to ask about more conservative understanding of "type", which is class or a base class, using the methods you're asking about.
Upvotes: 9
Reputation: 12578
I also wouldn't call two many (is_a?
and kind_of?
are aliases of the same method), but if you want to see more possibilities, turn your attention to #class
method:
A = Class.new
B = Class.new A
a, b = A.new, B.new
b.class < A # true - means that b.class is a subclass of A
a.class < B # false - means that a.class is not a subclass of A
# Another possibility: Use #ancestors
b.class.ancestors.include? A # true - means that b.class has A among its ancestors
a.class.ancestors.include? B # false - means that B is not an ancestor of a.class
Upvotes: 5
Reputation: 369526
What is the difference?
From the documentation:
- - (Boolean)
instance_of?(class)
- Returns
true
ifobj
is an instance of the given class.
and:
- - (Boolean)
is_a?(class)
- (Boolean)kind_of?(class)
- Returns
true
ifclass
is the class ofobj
, or ifclass
is one of the superclasses ofobj
or modules included inobj
.
If that is unclear, it would be nice to know what exactly is unclear, so that the documentation can be improved.
When should I use which?
Never. Use polymorphism instead.
Why are there so many of them?
I wouldn't call two "many". There are two of them, because they do two different things.
Upvotes: 25