検証内容
RUBY_VERSION
# => "2.7.1"
# Integerの祖先
Integer.ancestors
# => [Integer, Numeric, Comparable, Object, Kernel, BasicObject]
kind_of? (is_a?)
is_a?
はエイリアス
定義
レシーバーが以下のいずれかに当てはまる場合、trueを返す。
- 引数のクラスあるいはそのサブクラスのインスタンス
- 引数のモジュールをインクルードしたクラスあるいはそのサブクラスのインスタンス
つまりレシーバーはインスタンス、引数はクラスあるいはモジュールである必要がある。
検証
Numeric.new.kind_of?(Integer)
# => false
Numeric.new.kind_of?(Numeric)
# => true
Numeric.new.kind_of?(Object)
# => true
# インスタンスは引数に取れない
Numeric.new.kind_of?(1)
# TypeError (class or module required)
補足
# レシーバーがクラスの場合
Numeric.kind_of?(Integer)
# => false
Numeric.kind_of?(Numeric)
# => false
Numeric.kind_of?(Object)
# => true
なぜこのようなことが起こるかというと、全てのクラスはClassクラスのインスタンスであるため。
以下のようにClassクラスはObjectクラスを継承しているため、true が返る。
Numeric.class
# => Class
Class.ancestors
# => [Class, Module, Object, Kernel, BasicObject]
===
# クラス同士を比較した場合全て false
Numeric === Integer
# => false
Numeric === Numeric
# => false
Numeric === Object
# => false
# インスタンス同士の比較も全て false
1 === Numeric.new
# => false
Numeric.new === Numeric.new
# => false
Object.new === Numeric.new
# => false
# 比較対象のインスタンスが比較元のクラスと同じかその子孫だと true
Numeric === 1
# => true
Numeric === Numeric.new
# => true
Numeric === Object.new
# => false
# 逆は成り立たない
1 === Numeric
# => false
Numeric.new === Numeric
# => false
Object.new === Numeric
# => false
おまけ
Boolean を判定したいとき
# ruby に Boolean クラスは存在しないので怒られる
Boolean === true
# NameError (uninitialized constant Boolean)
val == true || val == false
# => true
gem も公開されている
https://rubygems.org/gems/boolean/versions/1.0.1
参考
https://docs.ruby-lang.org/ja/2.7.0/method/Object/i/kind_of=3f.html
https://docs.ruby-lang.org/ja/2.7.0/method/Module/i/=3d=3d=3d.html
https://qiita.com/fukumone/items/76e4f04a5188f4abb061
https://docs.ruby-lang.org/ja/2.7.0/class/Class.html