Section 4. Symbols

When you start programming in Ruby on Rails, you see a lot of funny little constructions that look somewhat like strings but start with colons rather than quotation marks:

Image

You might wonder what that funny little colon is doing in the front of :controller or :action. “Those are symbols, and they are very important,” the typical Rails tutorial replies, “but we have to move on.” Okay, but what are symbols? A symbol in Ruby is basically an immutable string. This is a useful abstraction for representing enumerated values in terms of performance and memory consumption. Because symbols are immutable, multiple references can refer to a single spot of storage in memory. It does not matter whether there are one or one million variables with the value: action in your code; they all use a single shared location in memory. In addition, comparing whether two symbol references are the same is trivial, because you need merely check that they point to the same location in memory. Symbols are certainly efficient.

However, this does not really explain the prevalence of symbols in Ruby on Rails, where you run into symbols everywhere! In the previous examples, you can see symbols used to name arguments for functions or as keys for hash tables (that is, as names) or in some cases where the code is using them as values, too (for example, :all and :position). This might seem a little strange. Why not just use strings? Does Rails really need to wring out that minor bit of optimization from symbols? Hardly. Instead, Rails’s extensive use of symbols reflects a rather common but underacknowledged Rubyism: Symbols denote specialness. More explicitly, the use of a symbol indicates that the name or value is not an arbitrary string but one of a limited set of expected values. This is also known as an enumeration in other languages, but Ruby does not require you to define the list of allowed values beforehand. Ruby allows you to define new symbols ad hoc when you need them. In this case, the use of symbols is a clue to the user that link_to is expecting only a limited number of named arguments that match the symbols.

Astute readers might already know that Ruby also allows users to define constants. These identifiers starting with capital letters are used to substitute values in for a name. So, if we are calculating the circumference of a circle, we can express that formula as diameter * Math::PI, and the PI is replaced with 3.14159… at execution time. Constants are indeed useful, and you might wonder why Ruby needs both constants and symbols. Couldn’t we just use for symbols constants that we don’t care about the value of? This is, after all, the approach commonly used in other languages for enumerations. Yes, but why should we here? The whole point of constants is that they represent something else (for example, Math::PI represents a numeric value), whereas symbols represent nothing but themselves. Furthermore, doing enumerations with constants is a pain: They need to be defined before actual use; they need to be scoped within a class or module; and it is all too easy to accidentally sow confusion with them. To see what I mean, consider how we might implement the named arguments to link_to without symbols:

Image

This code could work, but it is both a lot more verbose and a lot less flexible. If we want to add a new argument to link_to (perhaps a Style argument that takes a string of CSS), we must add code in two separate places: an implementation within the link_to method and a separate declaration of the Style constant in the module. In addition, you might have noticed my declaration for the Style constant introduced a subtle bug; I accidentally added the constant with the same value as Action. This means if we ever pass in the optional Style parameter to link_to, it will accidentally be interpreted as another Action. Because symbols only represent themselves, there is no way for code to confuse :action and :style. And I can add support for style without having to predeclare it in the ActionController module somewhere. Simple to use and well suited for their purpose, symbols are one of the unique features of Ruby.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset