Ruby:kind_of?対instance_of?対is_a?


488

違いはなんですか?どちらを使用すればよいですか?なぜそんなにたくさんあるのですか?


18
両方が存在する理由についてはis_a?kind_of?Rubyの設計哲学の一部だと思います。Pythonは、何かを行う方法は1つだけであると言っています。Rubyには多くの場合、同義のメソッドがあるため、より良い音のメソッドを使用できます。それは好みの問題です。部分的には日本の影響によるかもしれません。より良い音にするために、文によっては同じ数字に異なる単語を使用すると言われています。マッツは彼の言語デザインにその考えを持ち込んだかもしれません。
ネイサンロング、

@NathanLong日本のカウンターはあまり関係がないと思います。すべての言語には何らかの合意があるため、ほとんどの場合、あるカウンターを別のカウンターに置き換えることはできません(たとえば、平らなオブジェクトにシリンダーカウンターを使用することはできません。これは間違っています)。そして、それはユーフォニーよりも意味論と関係があります。
ケーシー

回答:


622

kind_of?is_a?同義です。

instance_of?他の2つとは異なりtrue、オブジェクトがサブクラスではなく、その正確なクラスのインスタンスである場合にのみ返されます。

例:

  • "hello".is_a? Objectそして、"hello".kind_of? Objectリターンtrueために"hello"あるStringStringのサブクラスですObject
  • ただしを"hello".instance_of? Object返しますfalse

77
それは時々よく読みます。考えてみて@honda.kind_of? Car@person.is_a? Administrator、美学についてRubyのすべて。実際、文法エラーに注意してください...アクティブなサポートを使用して、次のように書くことができます@person.is_an? Administrator:)...実際には、Rubyコアになっている可能性があります。
rfunduk

2
それは興味深い理由です。あなたはこれを壊すことができますか?以下のようなあなたがオーバーライドすることができkind_of?なくis_a?
Claudiu

3
@ thenduks、is_an?ruby-1.9.2-p0 にはありません。@Claudiu、いいえ。is_a?はの単なるエイリアスですkind_of?。どちらのメソッドも同じc関数を呼び出しrb_obj_is_kind_ofます。
ma11hew28

9
@Matt:エイリアスされた関数をオーバーライドせずにエイリアスをオーバーライドできます。したがって、はい、オーバーライドするkind_of?ことなくオーバーライドできますis_a?
sepp2k

4
このActiceSupport is_an?メソッドはどこにありますか?!現在のRailsバージョンにはないので、Googleで非推奨になることについては何も見つかりません。
トム卿

22

違いはなんですか?

ドキュメントから:

-(ブール値instance_of?(class)
が指定されたクラスのインスタンスであるtrueかどうかを返しますobj

そして:

-(ブールis_a?(class)
-(ブールkind_of?(class)
戻り値trueの場合は、classのクラスであるobj場合、またはclassのスーパークラスの一つであるobjかに含まれるモジュールobj

それが不明確な場合は、正確に何が不明確であるかを知っておくと、ドキュメントを改善できます。

どちらを使用すればよいですか?

決して。代わりにポリモーフィズムを使用してください。

なぜそんなにたくさんあるのですか?

私は2つを「多く」とは呼びません。2つの異なることを行うため、2つあります。


3
私の混乱は、3つあり、2つは同じことを行い、名前が異なるだけだったと思います。多態性の使用について-同意しますが、Ruby標準ライブラリはこれらのそれぞれの使用法でいっぱいです
Claudiu

4
多態性とはどういう意味ですか?ダックタイピングと同じですか?
アンドリューグリム

2
はい、同じです。アヒルのタイピングは、ポリモーフィズムの一種です。
SpaceGhost 2013年

3
多くの場合、ポリモーフィズムを実行する方が適切ですが、ファイルを処理しているときなど、特定のクラスがあることを本当に知りたいという境界ケースがあります。
Automatico

6

オブジェクトを使用して、必要なメソッドに応答するかどうかをオブジェクトに尋ねるのは、Rubyに似ていますrespond_to?。これにより、最小限のインターフェイスと実装を意識しないプログラミングの両方が可能になります。

もちろん、常に適用できるとは限りません。したがって、求めているメソッドを使用して、クラスまたは基本クラスである「タイプ」のより保守的な理解について質問する可能性はまだあります。


5
状況によります。コメントとブログの両方がcreated_atに応答する場合があります。そのような状況ではis_a?より適切な私見です
penkovsky

これは意味がありません。CommentオブジェクトとBlogオブジェクトを区別する必要がある場合は、created_atを使用しないでください。これは、created_atに応答するオブジェクトを取得するメソッドを作成できることを妨げるものではありません。それがその仕事をするのに他に何も必要としないなら、あなたはコメントやブログ、あるいはかなり他のどんなActiveRecordモデルでも安全にそれを使うことができます。
キングドン

3

私はまた、多くの2を呼び出す(ないだろうis_a?kind_of?同じ方法の別名です)が、あなたはより多くの可能性を見たい場合は、あなたに注意を向ける#class方法:

A = Class.new
B = Class.new A

a, b = A.new, B.new
b.class < A # true - means that b.class is a subclass of A
a.class < B # false - means that a.class is not a subclass of A
# Another possibility: Use #ancestors
b.class.ancestors.include? A # true - means that b.class has A among its ancestors
a.class.ancestors.include? B # false - means that B is not an ancestor of a.class

1
ありがとう-私は確かに「Rubyで収集できる実行時の型情報とその方法」という一般的な意味で質問していた-これは十分な例を提供する
Claudiu
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.