Il modo più conciso per testare l'uguaglianza delle stringhe (non l'uguaglianza degli oggetti) per stringhe o simboli Ruby?


87

Lo faccio sempre per testare l'uguaglianza delle stringhe in Ruby:

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

È questo il modo corretto per farlo senza testare l'uguaglianza degli oggetti?

Sto cercando il modo più conciso per testare le stringhe in base al loro contenuto.

Con le parentesi e il punto interrogativo, questo sembra un po 'goffo.

Risposte:



15

Il codice di esempio non si è espanso su una parte dell'argomento, ovvero i simboli, e quindi quella parte della domanda è rimasta senza risposta.

Se hai due stringhe, foo e bar, ed entrambe possono essere una stringa o un simbolo, puoi testare l'uguaglianza con

foo.to_s == bar.to_s

È un po 'più efficiente saltare le conversioni di stringhe sugli operandi di tipo noto. Quindi, se foo è sempre una stringa

foo == bar.to_s

Ma il guadagno di efficienza quasi certamente non vale la pena richiedere alcun lavoro extra da parte di chi chiama.

Prima di Ruby 2.2, evita di internare stringhe di input non controllate a scopo di confronto (con stringhe o simboli), perché i simboli non sono raccolti in modo spazzatura, e quindi puoi aprirti alla negazione del servizio attraverso l'esaurimento delle risorse. Limita l'uso dei simboli ai valori che controlli, ad esempio letterali nel codice e proprietà di configurazione affidabili.

Ruby 2.2 ha introdotto la garbage collection di simboli .


6
foo.intern == bar.internsarebbe meglio: internare una stringa è in media più efficiente che creare una stringa da un simbolo. (Se una determinata stringa è stata precedentemente internata, restituisce solo il simbolo.)
Chuck

4
In realtà non penso che sia una buona idea creare un simbolo da una stringa solo per risparmiare un po 'su alcuni confronti poiché perde simboli se la stringa non corrisponde. I simboli non sono Garbage Collection e quindi non devono essere creati se non si intende mantenerli, altrimenti si crea un vettore per un attacco Denial of Service.
Patru

Accidenti, non ci avevo pensato. Grazie, ho modificato la mia risposta in base al tuo commento.
sheldonh

1
Questo deve essere ribadito: "Evita di inserire stringhe di input non controllate [...] perché i simboli non vengono raccolti in modo spazzatura". Grazie @sheldonh.
Nate
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.