2011-10-13 28 views

risposta

149

Penso che stiate cercando instance_of?. is_a? e kind_of? restituiranno true per le istanze delle classi derivate.

class X < String 
end 

foo = X.new 

foo.is_a? String   # true 
foo.kind_of? String  # true 
foo.instance_of? String # false 
foo.instance_of? X  # true 
+6

Senza conoscere l'intento della domanda, direi che per la maggior parte delle situazioni di programmazione del mondo reale, "is_a?" È in realtà l'idioma più appropriato da usare (e spesso un controllo tipografico come quello di Andrew Grimm è ancora migliore). Un rigoroso confronto di classi è solitamente un odore di codice. http: //en.wikipedia.org/wiki/Liskov_substitution_principle – mahemoff

16

Si può fare:

foo.instance_of?(String) 

E più in generale:

foo.kind_of?(String) 
+3

Ciò che rende 'kind_of' più generale? Sembrano sinonimi: ['is_a'] (http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_object.html#Object.is_a_qm). – davidchambers

+2

@Davidchambers hai ragione, 'kind_of?' è un sinonimo di 'is_a?'. – steenslag

+0

@davidchambers: hai ragione, intendevo "instance_of?" Invece di "is_a?". –

6
foo.instance_of? String 

o

foo.kind_of? String 

se si o Non importa se è deserta da String da qualche parte sulla sua catena ereditaria

24

Un altro approccio anatra tipizzazione sarebbe dire

foo.respond_to?(:to_str) 

to_str indica che la classe di un oggetto non può essere un discendente effettiva della stringa, ma l'oggetto stesso è molto stringa simile (filante?).

+0

Fantastico. In questo caso capisco che 'foo' sarà' true', 'false', o una stringa vanilla, ma è bene apprendere soluzioni più generali. – davidchambers

+0

combina questo con una chiamata to_s dopo aver controllato se l'oggetto risponde a esso, e ti sei procurato una stringa! – seanmakesgames

+1

@seanmakesgames Intendevi 'to_str' o' to_s'? I due sono leggermente diversi. –

2

In aggiunta alle altre risposte, Class definisce il metodo === per verificare se un oggetto è un'istanza di tale classe.

  • o.class classe di o.
  • o.instance_of? c determina se o.class == c
  • o.is_a? c È o un'istanza di c o una delle sue sottoclassi?
  • o.kind_of? c sinonimo di * is_a? *
  • c === o per una classe o un modulo, determinare se * o.is_a? c * (String === "s" risultati true)
0

Credo che un modo migliore è quello di creare alcuni metodi predicato. Ciò salverà anche il tuo "Punto di controllo singolo".

class Object 
def is_string? 
    false 
end 
end 

class String 
def is_string? 
    true 
end 
end 

print "test".is_string? #=> true 
print 1.is_string?  #=> false 

Il più anatra modo di battitura;)

+1

cosa c'è di sbagliato con '" stringa ".is_a? (String)'. Sembra che tu stia reinventando la ruota. Esistono anche 'class',' instance_of', 'kind_of', ecc ... Scarsa idea di eseguire il patch delle scimmie nella classe' Object', per non parlare del fatto che sia inutile. – Mohamad

+0

Sono totalmente d'accordo con te :) Se il tuo focus è solo sui tipi di primitve e sai che i tuoi requisiti di progetto relativi ai tipi primitivi non cambieranno mai (ok è il solito, il caso;)) stai bene. Ma in un caso in cui i requisiti cambiano è meglio avere un "Punto di controllo unico". Ad esempio, nel tuo ambiente di progetto hai un sacco di pre-controlli (1000 e oltre). 'pre_check (" test ".is_string?)' Ora i requisiti del progetto cambieranno e ogni stringa con tre caratteri o più non è più definita come String (so che è insolita;)) Ora puoi cambiare facilmente il tuo metodo. – schlegel11

Problemi correlati