Verifique se uma variável é uma string no Ruby


Respostas:


205

Eu acho que você está procurando instance_of?. is_a?e kind_of?retornará true para instâncias de classes 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

9
Sem saber a intenção da pergunta, eu diria que para a maioria das situações de programação do mundo real, is_a?é realmente o idioma mais apropriado a ser usado (e muitas vezes uma verificação de digitação de pato como Andrew Grimm menciona é ainda melhor). Uma comparação estrita de classe geralmente é um cheiro de código. en.wikipedia.org/wiki/Liskov_substitution_principle
mahemoff 17/01

Rápido aparte: se você usar isso na lógica condicional, precisará usar parênteses; por exemplo, se foo.is_a (String) && ...?
dan

Como esperado, essa abordagem funcionará não apenas com String, mas também com Integere Float. Também funciona para Decimal? (as sublime texto intérprete destaca a sintaxe de forma diferente para Decimalo que me faz suspeitar)
stevec

29

Uma abordagem mais tipográfica seria dizer

foo.respond_to?(:to_str)

to_str indica que a classe de um objeto pode não ser um descendente real da String, mas o próprio objeto é muito parecido com uma string (string?).


Legal. Neste caso acontece que eu sei que foovai ser tanto true, falseou uma cadeia de baunilha, mas é bom para aprender soluções mais gerais.
Davidchambers #

combine isso com uma chamada to_s depois de verificar se o objeto responde a ela e você recebe uma string!
Seanmakesgames

1
@seanmakesgames Você quis dizer to_str, ou to_s? Os dois são um pouco diferentes.
Andrew Grimm


23

Você pode fazer:

foo.instance_of?(String)

E o mais geral:

foo.kind_of?(String)

4
O que torna kind_ofmais geral? Eles parecem ser sinónimo: is_a.
Davidchambers

2
@Davidchambers você está certo, 'kind_of?' é sinônimo de 'is_a?'.
213111111

@ Davidchambers: Você está certo, eu quis dizer, em instance_of?vez de is_a?.
Federico Builes

7
foo.instance_of? String

ou

foo.kind_of? String 

se você se importa apenas se for derivado de Stringalgum lugar na sua cadeia de herança


4

Além das outras respostas, Class define o método === para testar se um objeto é uma instância dessa classe.

  • classe o.class de o.
  • o.instance_of? c determina se o.class == c
  • o.is_a? c É uma instância de c ou qualquer uma de suas subclasses?
  • o.kind_of? c sinônimo de * is_a? *
  • c === o para uma classe ou módulo, determine se * o.is_a? c * ( String === "s" retorna verdadeiro)

-1

Eu acho que uma maneira melhor é criar alguns métodos predicados. Isso também salvará seu "Ponto Único de Controle".

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

A maneira mais digitação de pato;)


2
o que há de errado "string".is_a?(String)? Parece que você está reinventando a roda. Há também class, instance_of, kind_of, etc ... Bad idéia para monkey patch da Objectclasse, para não mencionar que é desnecessário.
Mohamad

Eu concordo totalmente com você :) Se seu foco é apenas nos tipos primitivos e você sabe que os requisitos do seu projeto relacionados a tipos primitivos nunca serão alterados (ok, geralmente é o caso;)) você está bem. Mas em um caso em que os requisitos mudam, é melhor ter um "Ponto Único de Controle". Por exemplo, no ambiente do seu projeto, você tem muitas verificações prévias (1000 e superiores). pre_check("test".is_string?) Agora, o requisito do seu projeto mudará e cada String com três caracteres ou mais não será mais definida como String (sei que é incomum;)) Agora você pode alterar seu próprio método facilmente.
precisa
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.