web-dev-qa-db-fra.com

Ruby: gentil_de? vs instance_of? vs is_a?

Quelle est la différence? Quand devrais-je utiliser lequel? Pourquoi sont-ils si nombreux?

463
Claudiu

kind_of? et is_a? sont synonymes. instance_of? est différent des deux autres en ce sens qu'il renvoie uniquement true si l'objet est une instance de cette classe exacte, pas une sous-classe.

Exemple: "hello".is_a? Object et "hello".kind_of? Object retournent true car "hello" est une String et String est une sous-classe de Object. Cependant, "hello".instance_of? Object renvoie false.

589
sepp2k

Quelle est la différence?

De la documentation:

--- (Boolean) instance_of?(class)
Renvoie true si obj est une instance de la classe donnée.

et:

--- (Boolean) is_a?(class)
--- (Boolean) kind_of?(class)
Renvoie true si class est la classe de obj ou si class est l'une des superclasses de obj ou des modules inclus dans obj.

Si cela n’est pas clair, il serait bon de savoir quoi exactement n’est pas clair, afin que la documentation puisse être améliorée.

Quand devrais-je utiliser lequel?

Jamais. Utilisez plutôt le polymorphisme.

Pourquoi sont-ils si nombreux?

Je n'appellerais pas deux "plusieurs". Il y en a deux, parce qu'ils font deux choses différentes.

21
Jörg W Mittag

Ruby ressemble plus à demander aux objets s'ils répondent à une méthode dont vous avez besoin, en utilisant respond_to?. Cela permet à la fois une interface minimale et une programmation ignorante de la mise en œuvre.

Bien entendu, il n’est pas toujours applicable. Il est donc toujours possible de poser des questions sur une compréhension plus conservatrice du "type", qui est une classe ou une classe de base, en utilisant les méthodes que vous demandez.

6
kuonirat

Je n’appellerais pas non plus deux noms nombreux (is_a? et kind_of? sont des alias de la même méthode), mais si vous souhaitez voir plus de possibilités, portez votre attention sur la méthode #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