Maneira mais concisa de testar a igualdade de strings (não igualdade de objetos) para strings ou símbolos Ruby?

86

Sempre faço isso para testar a igualdade das strings em Ruby:

if mystring.eql?(yourstring)
 puts "same"
else
 puts "different"
end

Esta é a maneira correta de fazer isso sem testar a igualdade do objeto?

Estou procurando a maneira mais concisa de testar strings com base em seu conteúdo.

Com os parênteses e o ponto de interrogação, isso parece um pouco desajeitado.

Bryan Locke
fonte

Respostas:

14

Seu exemplo de código não se expandiu em parte do seu tópico, a saber, símbolos, e essa parte da pergunta ficou sem resposta.

Se você tiver duas strings, foo e bar, e ambas podem ser uma string ou um símbolo, você pode testar a igualdade com

foo.to_s == bar.to_s

É um pouco mais eficiente ignorar as conversões de string em operandos com tipo conhecido. Então, se foo é sempre uma corda

foo == bar.to_s

Mas o ganho de eficiência quase certamente não vale a pena exigir nenhum trabalho extra em nome do chamador.

Antes do Ruby 2.2, evite internar strings de entrada não controladas para fins de comparação (com strings ou símbolos), porque os símbolos não são coletados como lixo e, portanto, você pode se abrir para negação de serviço por meio do esgotamento de recursos. Limite o uso de símbolos aos valores que você controla, ou seja, literais em seu código e propriedades de configuração confiáveis.

Ruby 2.2 introduziu a coleta de lixo de símbolos .

Sheldonh
fonte
6
foo.intern == bar.internseria melhor - internar uma string é mais eficiente em média do que criar uma string a partir de um símbolo. (Se uma determinada string foi internada anteriormente, ela apenas retorna o símbolo.)
Chuck
4
Na verdade, eu não acho uma boa ideia criar um símbolo a partir de uma string apenas para economizar um pouco em algumas das comparações, pois ele vazará símbolos se a string não corresponder. Os símbolos não são coletados como lixo e, portanto, não devem ser criados se você não tiver a intenção de mantê-los, caso contrário, você criará um vetor para um ataque de negação de serviço.
Patru
Puxa, eu não tinha pensado nisso. Obrigado, modifiquei minha resposta com base em seu comentário.
sheldonh de
1
Isso precisa ser reafirmado: "Evite internar strings de entrada não [...] controlada porque os símbolos não são coletados no lixo". Obrigado @sheldonh.
Nate