Most concise way to test string equality (not object equality) for Ruby strings or symbols?
Asked Answered
M

2

93

I always do this to test string equality in Ruby:

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

Is this is the correct way to do this without testing object equality?

I'm looking for the most concise way to test strings based on their content.

With the parentheses and question mark, this seems a little clunky.

Magistrate answered 10/11, 2009 at 19:1 Comment(0)
N
154

According to http://www.techotopia.com/index.php/Ruby_String_Concatenation_and_Comparison

Doing either

mystring == yourstring

or

mystring.eql? yourstring

Are equivalent.

Neogothic answered 10/11, 2009 at 19:5 Comment(0)
V
15

Your code sample didn't expand on part of your topic, namely symbols, and so that part of the question went unanswered.

If you have two strings, foo and bar, and both can be either a string or a symbol, you can test equality with

foo.to_s == bar.to_s

It's a little more efficient to skip the string conversions on operands with known type. So if foo is always a string

foo == bar.to_s

But the efficiency gain is almost certainly not worth demanding any extra work on behalf of the caller.

Prior to Ruby 2.2, avoid interning uncontrolled input strings for the purpose of comparison (with strings or symbols), because symbols are not garbage collected, and so you can open yourself to denial of service through resource exhaustion. Limit your use of symbols to values you control, i.e. literals in your code, and trusted configuration properties.

Ruby 2.2 introduced garbage collection of symbols.

Veasey answered 11/11, 2009 at 11:10 Comment(4)
foo.intern == bar.intern would be better — interning a string is more efficient on average than creating a string from a symbol. (If a given string has been previously interned, it just returns the symbol.)Debroahdebs
Actually I do not think it is a good idea to create a symbol out of a string just to economize a little on some of the comparisons since it will leak symbols if the string does not match. Symbols are not garbage collected and therefore should not be created if you do not intend to keep them, otherwise you create a vector for a denial of service attack.Percolate
Gee, I hadn't thought of that. Thanks, I've modified my answer based on your comment.Veasey
This needs to be restated: "Avoid interning uncontrolled input strings [...] because symbols are not garbage collected". Thank you @sheldonh.Throb

© 2022 - 2024 — McMap. All rights reserved.