Ruby - what's the difference between using a colon or quotation mark in a string?

In Ruby I can write some things in two different ways:

I can do this:

:algo

Or this:

'algo'

What's the difference?

Author: fotanus, 2014-04-17

2 answers

Short version : Use :simbolos for code control strings, and "strings" for what will appear on the user's screen.

The first thing that should be said is that you should not confuse strings with symbols. When you type :string, you are instantiating a symbol. When you write "string" you are instantiating a string. Let's see this in practice:

:string.class
 => Symbol 
'string'.class
 => String 

The methods that are available for objects String are not the same as those that are available for objects Symbol. So often these objects are not interchangeable.

The biggest difference between a symbol and a string is that a symbol is immutable . This means that once it is instanced, it is impossible to modify its value. A string, on the other hand, is changeable. For example, and possible to use the method tr! to change the value of a string:

 a = 'string'
=> "string"
 a
=> "string" # valor da string
 a.tr!('i', 'e')
=> "streng"
 a
=> "streng" # mesma variável possui outro valor agora

A very important difference is that an object of the symbol class never has its memory dislocated, different from a string. Ruby is an interpreted language that has a garbage collector - this means you don't have to manually allocate and deallocate memory as is required in lower-level languages like C (via the function malloc, for example). When you no longer use a string, the Ruby garbage collector discards that string. This never happens with symbols. To free the memory consumed by the symbols, there is only one way: leaving from your program.

When a program consumes more and more memory without ever releasing it, that program is leaking memory . If you leave it running forever, the memory used is getting bigger and bigger. This is not desirable for programs that will run for a long time, for example an application on Rails. To avoid this, one should not dynamically create symbols in the program in unknown strings. For example, using the to_sym in entrance of user data.

Now that I'm scared, let's get to the good part of the symbols: -)

Since they are immutable, it is not necessary to instantiate them every time they appear in the program. This means that he or ruby notices that there is already a symbol equal to that, and uses it again, as many times as necessary. Let's prove this:

 "minha string".object_id == "minha_string".object_id
 => false 
 :simbolo.object_id == :simbolo.object_id
 => true 

As you can see, the first row instantiates two different objects, while the second uses the same object twice. That's it it proves that ruby reuses symbols, but not strings.

Okay, cool. What about me with that? The problem is that instantiating or comparing strings takes much longer than instantiating or comparing symbols. So, despite losing a bit by constantly using more memory, operations done with symbols are usually faster.

As we have seen, the comparison of a symbol can be done with object_id, while a string is done by comparing the internal value. This is much more expensive for the processor, which works at the bit level, where numbers are represented using much less space than strings.

I do not say that you will compare a symbol manually. For example, using symbols as keys for an object of type Hash in which the values will be searched often greatly increases performance, precisely because the comparison of symbols is faster than of strings.

For their characteristics, the symbols were thought to be used for code control. For example, for keys in a dictionary or an attribute tipo of an object. You will constantly use these values in the code, and they are used for comparison (direct in the case of the attribute, implicit in the case of a key for a hash). So it is more advantageous to use symbols and avoid getting instantiating a new string each time your code is used.

Already the Strings shine when when the values are manipulated, or when they are defined dynamically. For example, for the nickname of a user of a site-there are many users and hardly everyone will enter the site at the same time, so there is no reason to use symbol and suffer from increased memory.

 13
Author: fotanus, 2014-05-21 23:00:31

When creating a string using :string, that string is unique throughout the program, i.e. the system checks if there is already a string with these characters, and if there is it reuses it, instead of creating a new one. This type of string is called symbol, and besides being unique it is also immutable.

While using 'string', a new object is created, usually without taking into account if there are already others with the same content (same sequence of characters) or not. In this way, Two strings can be "the same" but have different identities :

:algo == :algo         # true
:algo.equal? :algo     # true

'algo' == 'algo'       # true
'algo'.equal? 'algo'   # false

Source: this question in Soen (See also this other question )

Note: since strings and symbols are different types, comparing them using == will always return false, even if their contents are the same. If you have variables that can be of one type or another, and want to know if their content is the same, you can use .to_s in both comparison sides:

:algo == 'algo'             # false
:algo.to_s == 'algo'.to_s   # true

Example in ideone .

 6
Author: mgibsonbr, 2017-05-23 12:37:27