99

When using Ruby, I keep getting mixed up with the :.

Can someone please explain when I'm supposed to use it before the variable name, like :name, and when I'm supposed to use it after the variable like name:?

An example would be sublime.

nbro
  • 15,395
  • 32
  • 113
  • 196
FloatingRock
  • 6,741
  • 6
  • 42
  • 75
  • 3
    Thought this was a dupe at first, but all the questions I can find don't seem to mention the newer Hash syntax { key: val } – Some Guy Jul 09 '14 at 19:21
  • 1
    Isn't this covered by these questions? [1](http://stackoverflow.com/q/8675206/479863), [2](http://stackoverflow.com/q/10004158/479863), [3](http://stackoverflow.com/q/8675206/479863), [4](http://stackoverflow.com/q/8796358/479863), [5](http://stackoverflow.com/q/9694209/479863) – mu is too short Jul 09 '14 at 19:50
  • To varying degrees, but yes to the first one in particular. Didn't find that one when I was looking. – Some Guy Jul 09 '14 at 20:00
  • This should also be useful: [What is the colon operator in Ruby?](http://stackoverflow.com/questions/6337897/what-is-the-colon-operator-in-ruby) – jpw Jul 04 '15 at 12:28
  • 2
    Ruby 2.1 introduced 'required keyword arguments', which are defined with a trailing colon. See https://robots.thoughtbot.com/ruby-2-keyword-arguments That's whay this question was deemed as 'duplicate' mistakenly. – prograils Nov 18 '18 at 13:23

4 Answers4

71

This has absolutely nothing to do with variables.

:foo is a Symbol literal, just like 'foo' is a String literal and 42 is an Integer literal.

foo: is used in three places:

  • as an alternative syntax for Symbol literals as the key of a Hash literal: { foo: 42 } # the same as { :foo => 42 }
  • in a parameter list for declaring a keyword parameter: def foo(bar:) end
  • in an argument list for passing a keyword argument: foo(bar: 42)
Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • 4
    This line 'as an alternative syntax for Symbol literals as the key of a Hash literal: { foo: 42 } # the same as { :foo => 42 }' ripped out all my questions. Thank you. – Ricardo Silva Jul 04 '15 at 12:32
  • 1
    What does the syntax [without hash values](https://github.com/discourse/discourse/blob/9ce66038647bc4ff63167fe9c74857a01acc0875/app/models/post_alert_observer.rb#L2), e.g. `observe :post_action, :post_revision` mean? – Dan Dascalescu Sep 22 '15 at 07:46
  • 2
    @DanDascalescu: This is a message send, sending the message `observe` to `self` with two arguments, `:post_action` and `:post_revision`. – Jörg W Mittag Sep 22 '15 at 08:34
59

You are welcome for both, while creating Hash :

{:name => "foo"}
#or
{name: 'foo'} # This is allowed since Ruby 1.9

But basically :name is a Symbol object in Ruby.

From docs

Hashes allow an alternate syntax form when your keys are always symbols. Instead of

options = { :font_size => 10, :font_family => "Arial" }

You could write it as:

options = { font_size: 10, font_family: "Arial" }
Arslan Ali
  • 17,418
  • 8
  • 58
  • 76
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
  • Ok, and when passing a named parameter to a function, which do I use: `Model.create(:name "John")` or `Model.create(name: "John")`. They're not interchangeable, are they? – FloatingRock Jul 09 '14 at 19:14
  • `Model.create(:name "John")` is not valid.. `Model.create(:name =>"John")` is valid. – Arup Rakshit Jul 09 '14 at 19:14
  • Crystal clear now, thanks for the examples! – FloatingRock Jul 09 '14 at 19:28
  • The 1.9 syntax, borrowed from JavaScript, does lead to a bit of confusion: `{ foo: :foo }` is equivalent to `{ :foo => :foo }` even though it looks like two different things. – tadman Jul 09 '14 at 19:31
  • @tadman I forgot to mention. Thanks for mentioning here. – Arup Rakshit Jul 09 '14 at 19:33
  • 3
    The JavaScript style notation requires that symbols be [valid labels](http://stackoverflow.com/a/9694676/479863) so you can't use it with all sorts of valid symbols like `:$set` (quite common when working with MongoDB), `:'where is pancakes house?'`, `:[]`, `:@x`, ... – mu is too short Jul 09 '14 at 19:49
  • @muistooshort Your *knowledge* is equivalent to a depth of *sea*. – Arup Rakshit Jul 09 '14 at 19:54
  • 2
    No, this is just my Ruby pet peeve. This has got to be the most confusing thing Matz ever did to Ruby :( – mu is too short Jul 09 '14 at 19:59
  • 1
    @muis waytooshort, let's start a list. How about `singleton class` vs. `metaclass` vs. `anonymous class`, `reduce` vs `inject` etc.? – Cary Swoveland Jul 10 '14 at 17:53
  • 2
    Arup, please clarify your comment address to @muistooshort. Which sea? Greatest depth is 6,946 meters for the Carribean Sea, a mere 14m for the Sea of Azov. – Cary Swoveland Jul 10 '14 at 17:59
  • @CarySwoveland, could be 10,994 meters in the Mariana Trench… – dlu Feb 05 '16 at 05:13
  • 1
    @CarySwoveland :) .. – Arup Rakshit Feb 05 '16 at 06:12
  • 2
    @dlu, I guess that depends on what Arup meant by "sea". If he meant the world ocean, the Mariana Trench would be appropriate; if he meant bodies of water that are regarded as seas (and generally have "sea" in their name), it would be the Carribean Sea. Regardless, we are agreed that mu is too short is a very deep thinker. – Cary Swoveland Feb 05 '16 at 06:15
  • @CarySwoveland Indeed, and that software types are very littoral (or not so) thinkers. Sorry, I couldn't resist. – dlu Feb 05 '16 at 07:52
11

:name is a symbol. name: "Bob" is a special short-hand syntax for defining a Hash with the symbol :name a key and the string "Bob" as a value, which would otherwise be written as { :name => "Bob" }.

Chuck
  • 234,037
  • 30
  • 302
  • 389
1

You can use it after when you are creating a hash.

You use it before when you are wanting to reference a symbol.

In Arup's example, {name: 'foo'} you are creating a symbol, and using it as a key.

Later, if that hash is stored in a variable baz, you can reference the created key as a symbol:

baz[:name]

vgoff
  • 10,980
  • 3
  • 38
  • 56
  • But you can't always use the JavaScript style notation when using symbols as keys in a Hash literal, `:$set => { ... }` for example. – mu is too short Jul 09 '14 at 19:52
  • This is true. There are exceptions. I thought the question was simply some examples. Going to read the question again... :) – vgoff Jul 09 '14 at 20:01
  • Thought I had mentioned JavaScript... But it was not I. – vgoff Jul 09 '14 at 20:03