Why are symbols in Ruby not thought of as a type of variable?

Symbols are not variables, but a type of literal value, like numerals and quoted strings. Significantly, symbols are used to represent variables and other named values in the Ruby runtime. So when the Ruby interpreter sees the name foo used as a variable or method name, what it looks up in the Hash of runtime values is the symbol :foo, not the string "foo". This was, in fact, the original use of the term "symbol" in programming language terminology; variables, functions, constants, methods, and so on are said to be stored in the compiler or interpreter's "symbol table".

Pretty much any time you're passing around the name of something in Ruby, you're going to use a symbol. If you use method_missing as a catch-all to implement arbitrary methods on your object class, a symbol is what it receives as an argument telling it the name of the method that was actually called. If you inspect an object with .methods or .instance_variables, what you get back is an array of symbols. And so on.


They aren't variables because they don't hold values, they are immutable. The thing is the value itself. It's similar to numbers. You can't set the value of 1. 1 = 2 doesn't work.


Symbols used in accessor methods are not variables. They are just representing the name of a variable. Variables hold some reference, so you cannot use a variable itself in defining accessor methods. For example, suppose you wanted to define an accessor method for the variable @foo in a context where its value is "bar". What would happen if Ruby's syntax were to be like this:

attr_accessor @foo

This would be no different from writing:

attr_accessor "bar"

where you have no access to the name @foo that you are interested in. Therefore, such constructions have to be designed to refer to variable names at a meta level. Symbol is used for this reason. They are not variables themselves. They represent the name of a variable.

And the variable relevant to accessor methods are instance variables.


attr_accessor and such are all methods that belong to the class, Class. They expect symbols as arguments. You could write your own version of attr_ that used strings, if you wanted. Its just a ruby idiom. Here's an example of attr_acessor that stores all the previous values of attr_accessor I made for a homework assignment.

class Class
  def attr_accessor_with_history(attr_name)
    attr_name = attr_name.to_s   # make sure it's a string
    attr_reader attr_name        # create the attribute's getter
    attr_reader attr_name+"_history" # create bar_history getter
    class_eval %Q"
      def #{attr_name}=(value)
        if !defined? @#{attr_name}_history 
          @#{attr_name}_history = [nil]
        end
        @#{attr_name} = value
        @#{attr_name}_history << value
      end
    "
  end
end