Controlla se una variabile è una stringa in Ruby


Risposte:


205

Penso che tu stia cercando instance_of?. is_a?e kind_of?restituirà true per istanze da 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

9
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 di battitura a papera come menzionato da Andrew Grimm è ancora migliore). Un rigoroso confronto di classe è solitamente un odore di codice. en.wikipedia.org/wiki/Liskov_substitution_principle
mahemoff

A parte veloce: se lo usi in logica condizionale devi usare le parentesi; ad esempio, if foo.is_a? (String) && ...
dan

Come previsto, questo approccio funzionerà non solo con String, ma anche con Integere Float. Funziona anche per Decimal? (il sublime interprete del testo evidenzia la sintassi in modo diverso per Decimalcui mi insospettisce)
stevec

29

Sarebbe da dire un approccio più anatra

foo.respond_to?(:to_str)

to_str indica che la classe di un oggetto potrebbe non essere un discendente effettivo della stringa, ma l'oggetto stesso è molto simile a una stringa (filante?).


Freddo. In questo caso mi capita di sapere che foosarà o true, falseo una stringa di vaniglia, ma è bene imparare soluzioni più generali.
davidchambers

combinalo con una chiamata to_s dopo aver verificato se l'oggetto risponde_ ad esso, e ti sei procurato una stringa!
seanmakesgames

1
@seanmakesgames Volevi dire to_str, o to_s? I due sono leggermente diversi.
Andrew Grimm


23

Tu puoi fare:

foo.instance_of?(String)

E il più generale:

foo.kind_of?(String)

4
Cosa rende kind_ofpiù generale? Essi sembrano essere sinonimi: is_a.
davidchambers

2
@Davidchambers hai ragione, "kind_of?" è un sinonimo di "is_a?".
Steenslag

@davidchambers: hai ragione, volevo dire instance_of?invece di is_a?.
Federico Builes

7
foo.instance_of? String

o

foo.kind_of? String 

se ti interessa solo se è deragliato da Stringqualche parte nella sua catena di eredità


4

Oltre alle altre risposte, Class definisce il metodo === per verificare se un oggetto è un'istanza di quella 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" restituisce true)

-1

Penso che un modo migliore sia creare alcuni metodi predicativi. Ciò salverà anche il tuo "punto di controllo unico".

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 modo di scrivere più anatra;)


2
cosa c'è che non va "string".is_a?(String). Sembra che tu stia reinventando la ruota. C'è anche class, instance_of, kind_of, ecc ... cattiva idea di patch di scimmia della Objectclasse, per non parlare che è inutile.
Mohamad

Sono totalmente d'accordo con te :) Se il tuo focus è solo sui tipi primitivi e sai che i requisiti del tuo progetto relativi ai tipi primitivi non cambieranno mai (ok di solito è così;)) stai bene. Ma nel caso in cui i requisiti cambino è meglio avere un "punto di controllo unico". Ad esempio, nel tuo ambiente di progetto hai molti controlli preliminari (1000 e oltre). pre_check("test".is_string?) Ora i requisiti del tuo progetto cambieranno e ogni stringa con tre caratteri o più non è più definita come stringa (lo so che è insolito;)) Ora puoi cambiare facilmente il tuo metodo.
schlegel11
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.