¿La forma más concisa de probar la igualdad de cadenas (no la igualdad de objetos) para cadenas o símbolos Ruby?

86

Siempre hago esto para probar la igualdad de cadenas en Ruby:

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

¿Es esta la forma correcta de hacer esto sin probar la igualdad de objetos?

Estoy buscando la forma más concisa de probar cadenas en función de su contenido.

Con los paréntesis y el signo de interrogación, esto parece un poco torpe.

Bryan Locke
fuente

Respuestas:

14

Su muestra de código no se expandió en parte de su tema, es decir, los símbolos, por lo que parte de la pregunta quedó sin respuesta.

Si tiene dos cadenas, foo y bar, y ambas pueden ser una cadena o un símbolo, puede probar la igualdad con

foo.to_s == bar.to_s

Es un poco más eficiente omitir las conversiones de cadenas en operandos con tipo conocido. Entonces, si foo es siempre una cadena

foo == bar.to_s

Pero es casi seguro que la ganancia de eficiencia no vale la pena exigir ningún trabajo adicional en nombre de la persona que llama.

Antes de Ruby 2.2, evite internar cadenas de entrada no controladas con el propósito de comparar (con cadenas o símbolos), porque los símbolos no se recolectan como basura, por lo que puede abrirse a la denegación de servicio a través del agotamiento de los recursos. Limite el uso de símbolos a los valores que controla, es decir, literales en su código y propiedades de configuración confiables.

Ruby 2.2 introdujo la recolección de basura de símbolos .

Sheldonh
fuente
6
foo.intern == bar.internSería mejor: intercalar una cadena es más eficiente en promedio que crear una cadena a partir de un símbolo. (Si una cadena dada ha sido internada previamente, simplemente devuelve el símbolo)
Chuck
4
En realidad, no creo que sea una buena idea crear un símbolo a partir de una cadena solo para economizar un poco en algunas de las comparaciones, ya que filtrará símbolos si la cadena no coincide. Los símbolos no se recolectan como basura y, por lo tanto, no deben crearse si no tiene la intención de conservarlos; de lo contrario, crea un vector para un ataque de denegación de servicio.
Patru
Vaya, no había pensado en eso. Gracias, modifiqué mi respuesta según tu comentario.
sheldonh
1
Esto debe reformularse: "Evite internar cadenas de entrada no controladas [...] porque los símbolos no se recolectan como basura". Gracias @sheldonh.
Nate