Ruby on RailsやRubyには、要素の型を確認し、指定した型にあっていればtrue、違えばfalseを返すメソッドとして、is_a?
, kind_of?
, instance_of?
が用意されています。
is_a?
, kind_of?
, instance_of?
のいずれも似たような処理をします。
ここではそれぞれの使い方や違いについて実例で解説しています。
is_a?, kind_of?, instance_of?の使い方
使い方
is_a?, kind_of?, instance_of?
の3つとも、指定した型にあっていればtrue、違えばfalseを返すメソッドで、基本的な使い方は同じです。
レシーバ.メソッド(型)
対象の要素(レシーバ)が引数で指定した型に一致していればtrue, 異なればfalseを返します。
is_a?の実例
arr = [1, 2, 3]
arr.is_a?(Array)
=> true
arr.is_a?(String)
=> false
配列に対して、型「Array」を引数に渡せばtrueが返ります。「String」を渡せば、falseが返ります。
kind_of?の実例
arr = [1, 2, 3]
arr.kind_of?(Array)
=> true
arr.kind_of?(String)
=> false
instance_of?の実例
arr = [1, 2, 3]
arr.instance_of?(Array)
=> true
arr.instance_of?(String)
=> false
配列に対して、型「Array」を引数に渡せばtrueが返ります。「String」を渡せば、falseが返ります。
主な型の種類一覧
is_a?, kind_of?, instance_of?
メソッドの引数で指定できる主な型には以下のようなものがあります。
型 | 内容 | 要素の例 |
---|---|---|
String | 文字列 | “string” |
Integer | 整数 | 100 |
Float | 小数 | 1.23 |
Array | 配列 | [1, 2, 3] |
Range | 範囲 | 1..3 |
Hash | ハッシュ | {:a=>1, :b=>2, :c=>3} { a: 1, b: 2, c: 3} |
Class | クラス | class クラス名 処理 end |
Module | モジュール | module モジュール名 処理 end |
is_a?とkind_of?の違いは何か?
is_a?
とkind_of?
の違いはありません。同じです。
kind_of?
はis_a?
のエイリアスなので処理は同じ処理をします。
文字数が少ないis_a?
を使う方が一般的かと思います。
is_a?とinstance_of?の違いは何か?
is_a?
とinstance_of?
には明確な違いがあります。それはinstance_of?はレシーバーのみ評価するのに対し、is_a?はスーパークラスの型も評価します。
スーパークラスとは、現在の要素のクラスの親クラスのことです。is_a?
では引数にスーパークラスの型が入っている場合でもtrueを返します。
スーパークラスとは何か?については後述しています。
実例:is_a?
とinstance_of?
の違い
arr = [1, 2, 3]
arr.is_a?(Object)
=> true
arr.instance_of?(Object)
=> false
Rubyにおいて、Arrayというクラスは、Objectというクラスの中の一つです。すなわち、ObjectはArrayのスーパークラスということです。
このため、is_a?
はtrue、instance_of?
はfalseとなります。
スーパークラスとは何か?
Rubyでは各要素の型にはクラスがあります。そのクラスの親となっているクラスのことをスーパークラスと呼びます。(上の階層のクラスのこと)
スーパークラスの例
Rubyのクラスの概念がわかりにくいかもしれません。整数型を表すIntegerを例にすると以下のようになっています。
Rubyにおける型のクラスの構造を図にすると以下のようになります。
BasicObject(最上位のクラス)
↓
Object
↓
String, Numeric, Module, Class,,,
↓
Integer, Float
スーパークラスの確認方法(superclassメソッド)
スーパークラスを確認するメソッドに「superclass」があります。これを実行すると、親となるクラス(スーパークラス)を表示してくれます。
型.superclass
実例
p Integer.superclass
//出力
Numeric
p BasicObject.superclass
p Object.superclass
p Numeric.superclass
p Integer.superclass
//出力
nil
BasicObject
Object
Numeric
BasicObjectは最上位のクラス
型の中で全ての型が属する最上位のクラスは「BasicObject」です。
このため「BasicObject」に対してsuperclassメソッドを実行すると、結果は「nil」となります。
p BasicObject.superclass
//出力
nil
各要素の型(クラス)とスーパークラスの関係
主要な要素とその型(クラス)とスーパークラスの関係は以下のようになっています。
要素 | 型(クラス) | スーパークラス | スーパークラスのスーパークラス |
---|---|---|---|
“string” | String | Object | Basic Object |
100 | Integer | Numeric | Object |
1.23 | Float | Numeric | Object |
[1, 2, 3] | Array | Object | Basic Object |
1..3 | Range | Object | Basic Object |
{:a=>1, :b=>2, :c=>3} | Hash | Object | Basic Object |
クラス | Class | Object | Basic Object |
モジュール | Module | Object | Basic Object |
nil | NilClass | Object | Basic Object |
is_a?使用時の注意点
上位のクラスを指定するとtrueが返る
is_a?
メソッドの引数にスーパークラスを指定した場合もtrueになるため、全てのデータが該当するObjectやBasic Objectを指定するとtrueが返ってしまいます。
obj = {:a=>1, :b=>2, :c=>3}
obj.is_a?(BasicObject)
=> true
100.is_a?(BasicObject)
=> true
"文字列".is_a?(BasicObject)
=> true
クラス名を指定するとfalseになる
is_a?は引数でクラス(型)を指定するものです。仮に、クラス名を指定した場合はfalseとなってしまうので注意してください。
class Aaa
end
##クラスの継承
class Bbb < Aaa
end
##クラス名を指定するとfalseになる
Bbb.is_a?(Bbb)
=> false
##スーパークラスのクラス名を指定するとfalseになる
Bbb.is_a?(Aaa)
=> false
##型を指定すればtrueが返る
Bbb.is_a?(Class)
=> true
is_a?の実際の使用例
is_a?を実際に処理の中で使う場合は、例えばif文で変数の型を判断して条件処理を行う場合があります。
def _article_items
if article_items.is_a?(Hash)
[
article_items.fetch('default')
]
elsif article_items.is_a?(Array)
article_items
else
[]
end
end