Ruby: kind_of? vs. instance_of? contro is_a?

Qual è la differenza? Quando dovrei usare quale? Perché ce ne sono così tanti?

kind_of? e is_a? sono sinonimi instance_of? è diverso dagli altri due in quanto restituisce true solo se l’object è un’istanza di quella class esatta, non una sottoclass.

Esempio: "hello".is_a? Object "hello".is_a? Object e "hello".kind_of? Object "hello".kind_of? Object return true perché "hello" è una String e String è una sottoclass di Object . Comunque "hello".instance_of? Object "hello".instance_of? Object restituisce false .

Qual è la differenza?

Dalla documentazione:

– ( Boolean ) instance_of?(class)
Restituisce true se obj è un’istanza della class data.

e:

– ( Boolean ) is_a?(class)
– ( Boolean ) kind_of?(class)
Restituisce true se class è la class di obj , o se class è una delle superclassi di obj o dei moduli inclusi in obj .

Se ciò non è chiaro, sarebbe bello sapere cosa esattamente non è chiaro, in modo che la documentazione possa essere migliorata.

Quando dovrei usare quale?

Mai. Usa invece il polimorfismo.

Perché ce ne sono così tanti?

Non chiamerei due “molti”. Ce ne sono due, perché fanno due cose diverse.

È più simile a Ruby chiedere agli oggetti se rispondono o meno a un metodo di cui hai bisogno, usando respond_to? . Ciò consente sia un’interfaccia minima che una programmazione inconsapevole di implementazione.

Ovviamente non è sempre applicabile, quindi c’è ancora la possibilità di chiedere una comprensione più prudente del “tipo”, che è di class o di una class base, usando i metodi che stai chiedendo.

Inoltre non chiamerei due molti ( is_a? E kind_of? Sono alias con lo stesso metodo), ma se vuoi vedere più possibilità, rivolgi la tua attenzione al metodo #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