Compruebe si una variable es una cadena en Ruby

Respuestas:

205

Creo que estás buscando instance_of?. is_a?y kind_of?devolverá verdadero para instancias de clases derivadas.

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
Cándido
fuente
9
Sin conocer la intención de la pregunta, diría que para la mayoría de las situaciones de programación del mundo real, is_a?es en realidad el idioma más apropiado para usar (y a menudo una verificación de tipeo como Andrew Grimm es incluso mejor). Una comparación de clases estricta suele ser un olor a código. en.wikipedia.org/wiki/Liskov_substitution_principle
mahemoff
Aparte de eso: si usa esto en lógica condicional, debe usar paréntesis; por ejemplo, si foo.is_a? (String) && ...
dan
Como era de esperar, este enfoque funcionará no solo con String, sino también con Integery Float. ¿También funciona para Decimal? (el intérprete más destacado de texto sublime la sintaxis diferente para Decimallo que me hace sospechar)
stevec
29

Un enfoque más tipo pato sería decir

foo.respond_to?(:to_str)

to_str indica que la clase de un objeto puede no ser un descendiente real de String, pero el objeto en sí es muy parecido a una cadena (¿fibroso?).

Andrew Grimm
fuente
Frio. En este caso me he enterado de que fooo bien habrá true, falseo una cadena de vainilla, pero es bueno aprender soluciones más generales.
davidchambers
combine esto con una llamada to_s después de verificar si el objeto responde_a él, ¡y obtuvo una cadena!
seanmakesgames
1
@seanmakesgames ¿Querías decir to_stro to_s? Los dos son ligeramente diferentes.
Andrew Grimm
stackoverflow.com/questions/11182052/… Re: comentario de andrew.
seanmakesgames
23

Tu puedes hacer:

foo.instance_of?(String)

Y el más general:

foo.kind_of?(String)
Federico Builes
fuente
4
¿Qué hace kind_ofmás general? Parecen ser sinónimo: is_a.
davidchambers
2
@Davidchambers tienes razón, '¿tipo_de?' es un sinónimo de 'is_a?'.
steenslag
@davidchambers: Tienes razón, quise decir en instance_of?lugar de is_a?.
Federico Builes
7
foo.instance_of? String

o

foo.kind_of? String 

si solo te importa si se deriva de Stringalgún lugar en su cadena de herencia

Mateo
fuente
4

Además de las otras respuestas, Class define el método === para probar si un objeto es una instancia de esa clase.

  • o.clase clase de o.
  • o.instance_of? c determina si o.class == c
  • o.is_a? c ¿Es o una instancia de c o alguna de sus subclases?
  • o.kind_of? c sinónimo de * is_a? *
  • c === o para una clase o módulo, determine si * o.is_a? c * ( String === "s" devuelve verdadero)
Steenslag
fuente
-1

Creo que una mejor manera es crear algunos métodos predicados. Esto también guardará su "Punto único de control".

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

La forma de escribir más pato;)

schlegel11
fuente
2
qué pasa con "string".is_a?(String). Parece que estás reinventando la rueda. También hay class, instance_of, kind_of, etc ... mala idea parche mono de la Objectclase, por no hablar de que es innecesario.
Mohamad
Estoy totalmente de acuerdo contigo :) Si te enfocas solo en los tipos primitivos y sabes que los requisitos de tu proyecto relacionados con los tipos primitivos nunca cambiarán (bueno, generalmente es el caso;)) estás bien. Pero en el caso de que los requisitos cambien, es mejor tener un "punto único de control". Por ejemplo, en el entorno de su proyecto, tiene muchas comprobaciones previas (1000 en adelante). pre_check("test".is_string?) Ahora el requisito de su proyecto cambiará y cada String con tres caracteres o más ya no se define como String (sé que es inusual;)) Ahora puede cambiar su propio método fácilmente.
schlegel11