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 .
foo.intern == bar.intern
seria 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.)