【Ruby】is_a?とは何か?kind_of?やinstance_of?との違いや注意点を実例で解説|型を確認し真偽値を返す方法

ruby-prograshi(プロぐらし)-kv ruby
記事内に広告が含まれていることがあります。

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?と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を例にすると以下のようになっています。

スーパークラスの例
  • 整数1のクラス(型)は「Integer」。
  • 「Integer」のスーパークラスは、数字全般を表す「Numeric」。
  • 「Numeric」のスーパークラスは、データ全般を表す「Object」。
  • 「Object」のスーパークラスは、識別やメソッドの指定など基本機能だけをもつ「BasicObject」。これが最上位のクラス。

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”StringObjectBasic Object
100IntegerNumericObject
1.23FloatNumericObject
[1, 2, 3]ArrayObjectBasic Object
1..3RangeObjectBasic Object
{:a=>1, :b=>2, :c=>3}HashObjectBasic Object
クラスClassObjectBasic Object
モジュールModuleObjectBasic Object
nilNilClassObjectBasic 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


タイトルとURLをコピーしました