Ruby

【Ruby】引数の型チェックを行うis_a?とinstance_of?メソッドについて

Ruby

 

今回は引数の型チェックを行うことができるメソッドis_a?instance_of?についてまとめてみました。型チェックを行うコードを記述する際、is_a?とinstance_of?の違いが微妙に分からなかったため自身の備忘録としてもまとめています。

is_a?メソッドとは

is_a?メソッドとは、レシーバ(対象の要素)が引数に指定した型かどうかをチェックするメソッドになります。指定した型であればtrue、そうでなければfalseを返します。

int = 1
int.is_a?(Integer)
=> true

str = 'Test'
str.is_a?(String)
=> true

int.is_a?(String)
=> false

str.is_a?(Integer)
=> false

is_a?と同様のメソッドとしてkind_of?メソッドが存在します。kind_of?はis_a?のエイリアスであるため、機能も使い方もis_a?と同じになります。

int = 1
int.kind_of?(Integer)
=> true

str = 'Test'
str.kind_of?(String)
=> true

int.kind_of?(String)
=> false

str.kind_of?(Integer)
=> false

instance_of?メソッドとは

instance_of?メソッドとは、is_a?メソッドと同様、レシーバ(対象の要素)が引数に指定した型かどうかをチェックするメソッドになります。指定した型であればtrue、そうでなければfalseを返します。

int = 1
int.instance_of?(Integer)
=> true

str = 'Test'
str.instance_of?(String)
=> true

int.instance_of?(String)
=> false

str.instance_of?(Integer)
=> false

is_a?とinstance_of?の違い

is_a?とinstance_of?はどちらもレシーバ(対象の要素)が指定した型かどうかをチェックするメソッドですが、厳密には違いがあります。

  • is_a?: レシーバの型だけでなく、そのスーパークラス(親クラス)もチェックする(includeしたモジュールも対象)
  • instance_of?: レシーバの型のみをチェックする

 

以下の例で見ていきます。

module Foo; end
module Bar; end

class Hoge
  include Foo
end

class Fuga < Hoge
  include Bar
end

fuga = Fuga.new

参考コード: instance_of?とis_a?の違い

is_a?の場合

以下の結果から、is_a?はレシーバの型だけでなくそのスーパークラスやincludeされたモジュールもチェックしていることが分かります。

fuga.is_a?(Fuga)
#=> true

fuga.is_a?(Hoge)
#=> true

fuga.is_a?(Object)
#=> true

fuga.is_a?(Foo)
#=> true

fuga.is_a?(Bar)
#=> true

instance_of?

その一方で、instance_of?はレシーバの型のみをチェックしていることが分かります。

fuga.instance_of?(Fuga)
#=> true

fuga.instance_of?(Hoge)
#=> false

fuga.instance_of?(Object)
#=> false

fuga.instance_of?(Foo)
#=> false

fuga.instance_of?(Bar)
#=> false

まとめ

  • is_a?メソッドは、レシーバ(対象の要素)が引数に指定した型かどうかをチェックするメソッド
  • instance_of?メソッドは、is_a?メソッドと同様、レシーバ(対象の要素)が引数に指定した型かどうかをチェックするメソッド
  • kind_of?はis_a?のエイリアスである
  • is_a?はレシーバの型だけでなく、そのスーパークラス(親クラス)もチェックする(includeしたモジュールも対象)
  • instance_of?はレシーバの型のみをチェックする

参考

 

今回は引数の型チェックを行うことができるメソッドis_a?とinstance_of?についてまとめました。実現したい内容によってis_a?とinstance_of?を使い分ける必要がありそうですね。