tags:

views:

112

answers:

4
+2  Q: 

Ruby and :symbols

Hi.

I have just started using Ruby and I am reading "Programming Ruby 1.9 - The Pragmatic Programmer's Guide". I came across something called symbols, but as a PHP developer I don't understand what they do and what they are good for.

Can anyone help me out with this?

A: 

Think of a Symbol as a either:

  • A method name that you plan to use later
  • A constant / enumeration that you want to store and compare against

For example:

s = "FooBar"
length = s.send(:length)
>>> 6
Paul Betts
Bear in mind `s.send("length")` yields the same result.
OscarRyz
@OscarRyz This is true, the distinction between Symbol and String has been highly diluted over the years - I just wanted to give the more "philosophical" meaning for Symbol
Paul Betts
It is not as much as "philosophical", but rather "conventional". And yep, the conventions are that they are often wherever you need to reference a method name, and as keys for hashes.
Chubas
+2  A: 

Symbols are similar to string literals in the sense that share the same memory space, but it is important to remark they are not string equivalents.

In Ruby, when you type "this" and "this" you're using two different memory locations; by using symbols you'll use only one name during the program execution. So if you type :this in several places in your program, you'll be using only one.

From Symbol doc:

Symbol objects represent names and some strings inside the Ruby interpreter. They are generated using the :name and :"string" literals syntax, and by the various to_sym methods. The same Symbol object will be created for a given name or string for the duration of a program‘s execution, regardless of the context or meaning of that name. Thus if Fred is a constant in one context, a method in another, and a class in a third, the Symbol :Fred will be the same object in all three contexts.

So, you basically use it where you want to treat a string as a constant.

For instance, it is very common to use it with the attr_accessor method, to define getter/setter for an attribute.

class Person 
   attr_accessor :name 
end
p = Person.new
p.name= "Oscar"

But this would do the same:

class DontDoThis
   attr_accessor( "name" )
end
ddt = DontDoThis.new
ddt.name= "Dont do it"
OscarRyz
Symbols aren't that similar to strings. sym = :something; sym.size gives an error. It's better to think of a symbol as a unique id (an integer) that can be referenced by a string constant.
Alkaline
@Alkaline: Yeap, that's why I emphasize in *similar* rather than *equivalent* or other word. Following your example, they should not be thought as integer either `:hola + :adios` gives an error too ;) . I guess a different word is needed.
OscarRyz
@OscarRyz: quite right :-) You can't do symbol arithmetics, although you can convert a symbol to an integer Symbol.to_i. But then you can also convert a symbol to a string (Symbol.to_s). Symbols are really unique objects that act like unique ID for hash keys, parameter names and the likes.
Alkaline
+4  A: 

It's useful to think of symbols in terms of "the thing called." In other words, :banana is referring to "the thing called banana." They're used extensively in Ruby, mostly as Hash (associative array) keys.

They really are similar to strings, but behind the scenes, very different. One key difference is that only one of a particular symbol exists in memory. So if you refer to :banana 10 times in your code, only one instance of :banana is created and they all refer to that one. This also implies they're immutable.

AboutRuby
A: 

@AboutRuby has a good answer, using the terms "the thing called".

:banana is referring to "the thing called banana."

He notes that you can refer to :banana many times in the code and its the same object-- even in different scopes or off in some weird library. :banana is the thing called banana, whatever that might mean when you use it.

They are used as

  • keys to arrays, so you look up :banana you only have one entry. In most languages if these are Strings you run the risk of having multiple Strings in memory with the text "banana" and not having the code detect they are the same
  • method/proc names. Most people are familiar with how C distinguishes a method from its call with parentheses: my_method vs. my_method(). In Ruby, since parentheses are optional, these both indicate a call to that method. The symbol, however, is convenient to use as a standin for methods (even though there really is no relationship between a symbol and a method).
  • enums (and other constants). Since they don't change they exhibit many of the properties of these features from other languages.
ndp