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.

Tags:

Ruby

Symbols