What is the colon operator in Ruby?
Just to demonstrate some of the things mentioned in the answers:
require 'benchmark'
n = 1_000_000
print '"foo".equal? "foo" -> ', ("foo".equal? "foo"), "\n"
print '"foo" == "foo" -> ', ("foo" == "foo" ), "\n"
print ':foo.equal? :foo -> ', (:foo.equal? :foo ), "\n"
print ':foo == :foo -> ', (:foo == :foo ), "\n"
Benchmark.bm(10) do |b|
b.report('string') { n.times { "foo".equal? "foo" }}
b.report('str == str') { n.times { "foo" == "foo" }}
b.report('symbol') { n.times { :foo.equal? :foo }}
b.report('sym == sym') { n.times { :foo == :foo }}
end
Running it outputs:
"foo".equal? "foo" -> false
"foo" == "foo" -> true
:foo.equal? :foo -> true
:foo == :foo -> true
So, comparing a string to a string using equal?
fails because they're different objects, even if they are equal content. ==
compares the content, and the equivalent checks with symbols are much faster.
user system total real
string 0.370000 0.000000 0.370000 ( 0.371700)
str == str 0.330000 0.000000 0.330000 ( 0.326368)
symbol 0.170000 0.000000 0.170000 ( 0.174641)
sym == sym 0.180000 0.000000 0.180000 ( 0.179374)
Both symbol tests are basically the same as far as speed. After 1,000,000 iterations there's only 0.004733 second difference, so I'd say it's a wash between which to use.
:foo
is a symbol named "foo". Symbols have the distinct feature that any two symbols named the same will be identical:
"foo".equal? "foo" # false
:foo.equal? :foo # true
This makes comparing two symbols really fast (since only a pointer comparison is involved, as opposed to comparing all the characters like you would in a string), plus you won't have a zillion copies of the same symbol floating about.
Also, unlike strings, symbols are immutable.