1

Hello I am ruby newbie :) I am trying to look for an explanation to understanding the use of ':' in its syntax.

E.g:

test "should create product" do
   assert_difference('Product.count') do
   post :create, product: @update
  end
end

When do we do :something as opposed to something: What is the difference. If this is googleable, please give me some pointers on the keywords to google about this topic. Variations of Ruby Colon so far yields a lot of irrelevant results.

Holger Just
  • 52,918
  • 14
  • 115
  • 123
user2511030
  • 515
  • 1
  • 4
  • 14

6 Answers6

6

In this case you are calling the function post with two parameters, the first parameter is the symbol :create and the second is a hash with the key :product and the value @update.

This line could be re-written as follows:

post(:create, {:product => @update})

The key: value style was introduced in Ruby 1.9.

Stefan
  • 109,145
  • 14
  • 143
  • 218
Han Loong Liauw
  • 341
  • 2
  • 3
  • ok now that is making sense completely. Post is the method which takes the symbol as param 1, and the value from the product hash against the key variable update. Amazing! Thank you for your help! – user2511030 Dec 12 '13 at 22:57
2

In both cases :foo references the Symbol :foo.

However, in the first case the Symbol is passed as a value to the post method. In the second case, the Symbol :foo is used as a key for an Hash.

You can rewrite the line as

post :create, :product => @update

which is a compacted version of

post :create, { :product => @update }

In the latter version it's more clear that :product is the key of a Hash.

Starting from Ruby 1.9, you can define a Hash using

foo: "bar"

instead of

:foo => "bar"

The 1.9 syntax has been largely adopted because compared to the "Rocket syntax" (the version :foo => "bar") is more concise.

Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
  • Simon thanks so post :create is taking create as the argument to the post method. Gotcha check. Thanks. Now product: @update is like saying product[update] ? – user2511030 Dec 12 '13 at 22:27
  • No, `@update` is an instance variable but unless you defined it before in the spec, then its value is `nil`. There is no correlation between `@update` and `product[update]`. – Simone Carletti Dec 12 '13 at 22:29
  • ok i do have a variable called @update: { title: 'lorem ipsum', description: 'wibbles', image_url: 'lorem.jpg', price: 19.95 } – user2511030 Dec 12 '13 at 23:00
2

This has been answered before and the answer leads you to this nice write up.

The Difference Between Ruby Symbols and Strings

Alistair
  • 1,064
  • 8
  • 17
  • He was not specifically asking about Symbols, but how a Symbol could possibly be created with two different syntaxes. – Simone Carletti Dec 12 '13 at 22:31
  • oh man! Ok. So we want to send an immutable string called create to the post method! I see we don't want to muck up and compromise the argument we send to post. – user2511030 Dec 12 '13 at 22:51
1

The short version is that:

  • when preceding an identifier, the colon identifies a Symbol literal (e.g. :name, :'string' or :"string")
  • when following an identifier in a Hash literal, the colon identifies a key that is a symbol, as in {key: value}.
  • in the context of a method parameter list, either as part of definition or as part of invocation, it represents a named parameter (e.g. def foo(param1: 1, param2: 2), foo(param1: 1, param2: 2)). In some cases, these named parameters are interpreted as hash keys as well.

Since there is no definitive source for the Ruby language at this point, it's hard to point you to a specific source. I suggest you consult the Ruby documentation site and find a source you like. All these topics will be covered there.

The Symbol literal syntax is introduced in the beginning of http://www.ruby-doc.org/core-2.0.0/Symbol.html. The Hash key syntax is covered in the beginning of http://www.ruby-doc.org/core-2.0.0/Hash.html.

The named parameter concept is a little tricky. Reference to follow.

As an aside, the colon is also used in the if-then-else operator, where it represents the else operator (e.g. condition ? this : that)

Community
  • 1
  • 1
Peter Alfvin
  • 28,599
  • 8
  • 68
  • 106
1

:something is called a symbol in Ruby. It is kind of a string (though it is not an instance of the String class) which is never garbage collected and of which there is ever only one incarnation each.

You always write symbols as either :something or :"something" (i.e. with a leading colon) except in one optional case: when using it as keys when using the new hash syntax introduced in Ruby 1.9.

Thus these two hashes are 100% the same:

{:a => "b"}
{a: "b"}

The difference is only syntactically, the hashes are the same. And this case is the only one where you would put the colon behind the symbol (as it also acts as the hash rocket in this case)

Holger Just
  • 52,918
  • 14
  • 115
  • 123
  • ok so for the immutable key expressed as :a, it holds a mutable string b as value which can be changed. Very nice. – user2511030 Dec 12 '13 at 22:53
0

Let's start with :something this is what is known as a symbol. Symbols are essentially strings, but there is only one instance of each symbol this is illustrated in the link above with the following example.

module One
  class Fred
  end
  $f1 = :Fred
end
module Two
  Fred = 1
  $f2 = :Fred
end
def Fred()
end
$f3 = :Fred
$f1.object_id   #=> 2514190
$f2.object_id   #=> 2514190
$f3.object_id   #=> 2514190

Now for the postfix case of something:. This detonates that something is a key in a hash. The following is a hash with a key a of value "test" hash = {a: "test"} it can also be written with the hold syntax like this {:a => "test"}

Hugo Tunius
  • 2,869
  • 24
  • 32