web-dev-qa-db-ja.com

ルビー:kind_of?vs. instance_of?対is_a?

違いはなんですか?いつ使うべきですか?どうしてそんなにたくさんあるの?

458
Claudiu

kind_of?is_a?は同義語です。 instance_of?は、オブジェクトがサブクラスではなくその正確なクラスのインスタンスである場合にのみtrueを返すという点で他の2つと異なります。

例:"hello".is_a? Objecttrueであり、StringStringのサブクラスであるため、"hello".kind_of? Objectおよび"hello"Objectを返します。ただし、"hello".instance_of? Objectfalseを返します。

582
sepp2k

違いはなんですか?

ドキュメントから:

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

そして:

- (ブール値is_a?(class)
- (ブール値kind_of?(class)
trueclassのクラスである場合、またはobjclassのスーパークラスまたはobjに含まれるモジュールのいずれかである場合は、objを返します。

それがはっきりしないなら、ドキュメンテーションを改良することができるように、正確にがはっきりしていないことを知っておくのはいいでしょう。

いつ使うべきですか?

しないでください。代わりに多態性を使用してください。

どうしてそんなにたくさんあるの?

私は2を「たくさん」とは呼ばないでしょう。 2つあります。それらは2つの異なることをするからです。

19
Jörg W Mittag

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

もちろん常に適用できるわけではないので、あなたが求めているメソッドを使って、クラスまたは基本クラスである "type"のもっと保守的な理解について尋ねる可能性がまだあります。

5
kuonirat

私はまた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
3
Boris Stitnicky