Ruby: kind_of? vs. instance_of? vs. is_a?
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
returntrue
because"hello"
is aString
andString
is a subclass ofObject
.- However
"hello".instance_of? Object
returnsfalse
.
Performance difference between is_a? / kind_of? vs class.name for class comparison in ruby
I would argue is_a?
is the correct one. Not because of performance but because of correctness.
Because it is perfectly fine to have multiple String classes in your app, it is not enough to just compare the class name. .class.name == 'String'
only returns if the name of the class is "String", but it doesn't tell if it is the same String
class that will be returned when you call String
in the current context.
Whereas kind_of?
does not only check if a
is an instance of String
. It would also return true
if a
is an instance of a subclass of String
.
You asked about what approach is most efficient but did not tell how you define efficient in the context of your question. is_a?
is the shortest, I would argue that is efficient. When you were thinking about performance, have a look at this:
require 'benchmark/ips'
string = "123"
Benchmark.ips do |x|
x.report("name == name") { string.class.name == "String" }
x.report("kind_of?") { string.kind_of?(String) }
x.report("is_a?") { string.is_a?(String) }
end
Warming up --------------------------------------
name == name 585.361k i/100ms
kind_of? 1.173M i/100ms
is_a? 1.299M i/100ms
Calculating -------------------------------------
name == name 5.870M (± 4.6%) i/s - 29.853M in 5.099899s
kind_of? 12.803M (± 3.0%) i/s - 64.514M in 5.043457s
is_a? 12.971M (± 3.6%) i/s - 64.935M in 5.012808s
Ruby: is_a? and instance_of? in BasicObject
You can steal is_a?
from Kernel
:
class My < BasicObject
define_method(:is_a?, ::Kernel.method(:is_a?))
end
m = My.new
m.is_a?(My) #=> true
m.is_a?(BasicObject) #=> true
m.is_a?(Object) #=> false
If you're going to build your own object hierarchy, you could also define your own Kernel
, something like:
module MyKernel
[:is_a?, :instance_of?, :class].each do |m|
define_method(m, ::Kernel.method(m))
end
end
class My < BasicObject
include ::MyKernel
end
is there a proper way to use is_a? with an instance_double?
I would do:
let(:response) { instance_double(Net::HTTPOK, :body => 'nice body!', :code => 200) }
before { allow(response).to receive(:is_a?).with(Net::HTTPOK).and_return(true) }
Count class instances in array
You can use Enumerable#grep
to fetch the instances of Car
:
array.grep(Car).size
Ruby - Instance_of? / is_a not working
Try:
if new_item.is_a?(classA)
@items << new_item
end
is_a?
is a method which returns true or false. As every method in ruby it can take a block, and as most of the methods it does absolutely nothing with it. So your <<
has never been executed.
Related Topics
Altering the Primary Key in Rails to Be a String
Creating Matrix With 'Array.New(N, Array.New)'
Cannot Load Such File - Script/Rails: Getting This Error While Remote Debugging Through Rubymine
Open an Io Stream from a Local File or Url
Is the Ruby Operator ||= Intelligent
How to Prevent Browser Page Caching in Rails
What Is the Easiest Way to Remove the First Character from a String
How to Use Ruby/Rails Variables Inside Sass
Why Am I Getting Objects Printed Twice
What Are the Brackets [5.1] After Activerecord Migration and How Does It Work
Installing Rubygems in Windows
Operator Precedence For And/&& in Ruby
Why Does Ruby 1.9.2 Remove "." from Load_Path, and What's the Alternative