What is the colon operator in Ruby?

RubySymbols

Ruby Problem Overview


When I say { :bla => 1, :bloop => 2 }, what exactly does the : do? I read somewhere about how it's similar to a string, but somehow a symbol.

I'm not super-clear on the concept, could someone enlighten me?

Ruby Solutions


Solution 1 - Ruby

: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.

Solution 2 - 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.

Solution 3 - Ruby

Symbols are a way to represent strings and names in ruby.

The main difference between symbols and strings is that symbols of the same name are initialized and exist in memory only once during a session of ruby.

They are useful when you need to use the same word to represent different things

Solution 4 - Ruby

There're some quotes from the famous book Agile Web Development with Rails, which may be helpful to understand the symbol as well : >Rails uses symbols to identify things. In particular, it uses them as keys when naming method parameters and looking things up in hashes.

redirect_to :action => "edit", :id => params[:id]

>You can think of symbols as string literals that are magically made into constants. Alternatively, you can consider the colon to mean "the thing named", so :id is "the thing named id".

Solution 5 - Ruby

In ruby each object has a unique object identifier, if you write puts "hello".object_id in your irb and hit return for 2 different times, you will get 2 different returning value,but if you write :hello.object_id 2 times you will only get the same one returning value. That should have explained the difference.

Solution 6 - Ruby

If you use :foo => bar, foo will be a symbol. The benefit to symbols is that they are unique. When you call on an item in the hash, you do hash[:foo].

Symbols require less memory than strings, which also makes them useful if you want to make your program a little faster.

Solution 7 - Ruby

All these answers omit one extra tantalising detail.. if you stringify the symbol :foo, you get.. guess what.. the string "foo". Hence

irb(main):025:0>
irb(main):026:0> :foo
=> :foo
irb(main):027:0> "#{:foo}"
=> "foo"
irb(main):028:0>
irb(main):029:0> 'foo' <=> :foo
=> nil
irb(main):030:0> 'foo' <=> :foo.to_s
=> 0
irb(main):031:0>

Hence.. for Perl programmers.. it's Ruby's answer to the 'bare word'.

Solution 8 - Ruby

It's a symbol. Basically, you are saying that the two elements of the hash have keys bla and bloop, much as if you had used the strings "bla" and "bloop". However, they take up less memory than strings and are easier to type.

Solution 9 - Ruby

If you are familiar with Java, you might be aware that Strings in Java are immutable. Symbols are similar in that sense in Ruby. They are immutable, i.e., any number of occurances of a particular symbol :symbol will map to only a single memory address. And, hence, it is recommended to use symbols wherever possible since it optimizes memory usage.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLuxuryModeView Question on Stackoverflow
Solution 1 - RubyChris Jester-YoungView Answer on Stackoverflow
Solution 2 - Rubythe Tin ManView Answer on Stackoverflow
Solution 3 - RubynunopoloniaView Answer on Stackoverflow
Solution 4 - Rubyshyan1View Answer on Stackoverflow
Solution 5 - RubyAlfred HuangView Answer on Stackoverflow
Solution 6 - RubyCharlesView Answer on Stackoverflow
Solution 7 - RubyFrank CarnovaleView Answer on Stackoverflow
Solution 8 - RubykindallView Answer on Stackoverflow
Solution 9 - RubyDhruva SagarView Answer on Stackoverflow