By allenemilyh

2012-12-13 00:16:11 8 Comments

New to programming and to Ruby, and I hope this question about symbols is in line. I understand that symbols in Ruby (e.g., :book, :price) are useful particularly as hash keys, and for all-around doing a lightweight, specific subset of the things that strings can do.

However, I am confused about symbols in one respect. Specifically, when they're used in the attr_accessor types of methods, it appears that they are behaving more like a variable. E.g., attr_reader :book, :price.

If true that they are variables in that usage, this is a bit puzzling because they are not typically listed among variable types (like the $global, @instance, local, @@class, and sometimes, CONSTANT, variable types) when variables types are described.

And if symbols are variables when used this way, what scope should be expected of them? Or are they still somehow lightweight strings in this context as well? (Or perhaps in some broader way, do symbols, strings, and variables all share a fundamental duck-like nature?) Thank you in advance for your insights and advice.


@nbit001 2013-09-04 00:30:22

Cool, I guess you understand them by now. However why are they so important?

Symbols in Ruby are immutable whereas strings are mutable. You think ok cool, so what?

Let's assume you have an array of strings, like so:

    [ "a", "b", "a", "b", "a", "b", "c" ]

For each new string you create ruby is going to create a string/object which holds the value of "a" and because strings are mutable things ruby assigns a different id to each of them. If you were to use symbols instead:

[ :a, :b, :a, :b, :a, :b, :c ]

Ruby now will point to those symbols and it will only create them once.

Let's do some benchmarking:

require 'benchmark' do |x|"Symbols") do
    a = :a
    1000_000.times do
      b = :a
  end"Strings") do
    a = "a"
    1000_000.times do
      b = "a"


ruby -w symbols.rb

Symbols  0.220000   0.000000   0.220000 (  0.215795)
Strings  0.460000   0.000000   0.460000 (  0.452653)

If you'd like to see all the symbols you have already created you could do:


You can also send a message to them asking about their id:

:a.object_id #=> 123
:a.object_id #=> 123

"a".id #=> 23323232
"a".id #=> some_blob_number

Again that's because Strings in Ruby are mutable and Symbols are not. Ruby Symbols represent names inside the Ruby Interpreter.

This video really helped me: Ruby's Symbols Explained

I hope it helps you all.

@BernardK 2012-12-14 02:12:56

(Answer to your comment)

dog = 'dog' or"dog")

After dog =, the field class of instance dog points to class String.

class << dog
    puts "inside #{self}" #=> inside #<Class:#<String:0x007fb38a83a820>>
    def bark
        puts 'woof'
dog.bark #=> "woof" 
p dog.singleton_methods #=> ["bark"]

With class << dog or def dog.bark, Ruby creates an anonymous class, the field class of instance dog now points to this anonymous class, and from there to String. Methods defined in this context with def or define_method go into the methods table of the anonymous class.

Ruby 1.9.2 has introduced Object#singleton_class. [The Pickaxe] Returns the singleton class of obj, creating one if necessary. (I add) It is equivalent to class << self; self end.

The Ruby Programming Language (O'Reiily) simply says : to open the eigenclass [singleton class] of the object o, use class << o.

So I don't know how to read it loud. I have read that some would prefer o >> class. It's only recently that I have found how to figure out what this strange expression means. I pronounce : go from o to it's anonymous class.

class << MyClass
    def dog
        puts 'dog as class method'
end #=> dog as class method

The same is true for a class. With class MyClass, MyClass, as instance of Class, is an object with a pointer to its class Class. With def MyClass.some_method or class << MyClass, Ruby creates an anonymous class which is inserted between MyClass and Class, and class methods go into it.

Maybe something like: "from class, instantiate singleton object self

Yes for "from class/object" to anonymous singleton class/eigenclass/metaclass. But we don't instantiate self. Self (in Smaltalk, this in C++/Java) is kind of a reserved word which designate the receiver of the message. dog.bark : in OO language we say that the message bark in sent to object dog. Inside the method bark, self will be set to dog, so that we can reference dog. This is more obvious with

o1 =; o2 =
o1.some_method; o2.some_method

some_method must be able to reference the receiver in a generic way, is it o1 or o2, this is what self is for.

@allenemilyh 2012-12-14 07:32:20

Thanks! Interesting stuff on singleton classes. I also like this link on the subject:

@allenemilyh 2012-12-14 07:42:00

Adding, also: I like the simple verbalization you suggested for the notation for class << MyClass -- "from class, go to its anonymous class". (I find discovering a way to pronounce a given notation to be very helpful!)

@BernardK 2012-12-14 08:12:51

@allenemilyh Thanks for the link, very good explanation, I have bookmarked it.

@BernardK 2012-12-13 13:46:01

To address your "If true that they are variables" and "scope" questions, it would have been simpler to answer that accessor symbols have nothing to do with instance variables, even if it sounds iconoclastic. They don't point to instance variables. Accessors only define getter and setter methods. Under Object#instance_variables, the Pickaxe(*) says : Note that simply defining an accessor does not create the corresponding instance variable.

In Ruby, a variable does not exist until you assign a value to it. The following code demonstrates this.

class MyClass
    attr_accessor :name
    attr_reader   :book

obj = # line 6
print '1) obj.instance_variables : '; p obj.instance_variables
print '2) : '; p = 'xyz'
print '3) obj.instance_variables : '; p obj.instance_variables
print '4) : '; p
print '5) : '; p

class MyClass
    def initialize(p_book)
        @book = p_book

obj ='The Pickaxe') # line 21
print '6) [new] : '; p

class MyClass
    method_name = 'title'
    attr_accessor method_name # line 26

obj.title = 'Programming Ruby'
print '7) obj.instance_variables : '; p obj.instance_variables
print '8) obj.title : '; p obj.title

Output :

$ ruby -w t.rb 
1) obj.instance_variables : []
2) : nil
3) obj.instance_variables : ["@name"]
4) : "xyz"
5) : nil
6) [new] : "The Pickaxe"
7) obj.instance_variables : ["@title", "@book"]
8) obj.title : "Programming Ruby"

1) empty array : accessors have not defined instance variables
2) asking for instance variable @name answers nil : it does not exist
3) assigning a value has created the instance variable.
Note that name = is a syntactic sugar for using the setter as an ordinary method with a parameter :'xyz')
4) the getter method name answers the value of @name
5) the getter method book answers nil because the instance variable @book does not exist. Defining an accessor attr_reader :book has not defined the corresponding instance variable
6) the getter method book answers the value assigned in initialize, called by new on line 21. The instance variable @book has been created by @book = p_book
line 26) I have always believed that accessors accept only symbols. I discover that a variable is possible, but of limited interest.
7) the setter method title= has created @title. This also shows that instance variables belong to a single object. We often believe that they belong to all instances of the class, as in other languages. In this case, @name belongs only to the object created on line 6.
8) the getter method title answers the value of @title

class MyClass
    def title # line 34
        @book + ' (cheating !)'

print '9) obj.title : '; p obj.title  

Output :

t.rb:34: warning: method redefined; discarding old title  
9) obj.title : "The Pickaxe (cheating !)"  

9) of course there is a tight correlation between an accessor symbol and the corresponding instance variable, because, behind the scene, Ruby creates methods which reference an instance variable of the same name. You could define your own getter and cheat.

Note that besides class variables (@@var, some dislike them as ugly as global variables), classes can also have instance variables. I call them class instance variables :).
class MyClass : Ruby allocates a new instance of class Class, defines a constant MyClass, and assigns the new instance to that constant. Thus MyClass is an ordinary object (instance of Class) and as such can have instance variables.

if RUBY_VERSION[0..2] == '1.8'
    class Object
        def singleton_class
            class << self

class MyClass
    singleton_class.instance_eval do
        attr_accessor :counter
    @counter = 0

    def initialize(p_book)
        @book = p_book
        self.class.counter += 1

print '10) MyClass.singleton_methods  : '; p MyClass.singleton_methods
print '11) MyClass.instance_variables : '; p MyClass.instance_variables
obj ='Ruby')
print '12) [new] ', MyClass.counter, ': '; p
obj ='Metaprogramming')
print '13) [new] ', MyClass.counter, ': '; p  

Output :

t.rb:55: warning: method redefined; discarding old initialize
10) MyClass.singleton_methods  : ["counter", "counter="]
11) MyClass.instance_variables : ["@counter"]
12) [new] 1: "Ruby"
13) [new] 2: "Metaprogramming"  

More on singleton methods here : What does def `self.function` name mean?


@allenemilyh 2012-12-13 22:08:45

Thanks! Aha, accessor methods define methods, not instance variables, as you nicely demonstrate in the first code block. (And, you can cause redefinition/renaming of a method.) I see from your last two code blocks that you can make one-off single-object methods (aka singleton methods), and that these can take accessor methods too. If read aloud, how would you read class << self? Maybe something like: "from class, instantiate singleton object self with the following one-off/special instructions"? Anyhoo, thank you again for the great clear example code!

@Mark Reed 2012-12-13 00:22:01

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.

@allenemilyh 2012-12-13 00:44:33

Thanks! Understanding how the compiler thinks in symbols helps!

@sawa 2012-12-13 01:14:34

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.

@allenemilyh 2012-12-13 01:20:02

Thanks, very helpful! Using an instance variable is too specific and would be interpreted by Ruby as the current value of that variable, so a symbol is used to represent the variable, generally.

@allenemilyh 2012-12-13 05:31:04

All the answers were helpful, but yours was clearest to me, and did the best at addressing the "why" (i.e., the need for symbols -- not just the what or how). Much appreciated!

@allenemilyh 2012-12-14 01:28:59

Note to readers who also have my question, please be sure to also see BernardK's answer below, with its helpful statement: "To address your 'If true that they are variables' and 'scope' questions, it would have been simpler to answer that accessor symbols have nothing to do with instance variables, even if it sounds iconoclastic. They don't point to instance variables. Accessors only define getter and setter methods." Indeed, accessor-method symbols define methods, as seen in this poster's output 2) below, which is nil and not a NoMethodError.

@Nick Colgan 2012-12-13 00:21:45

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.

@allenemilyh 2012-12-13 01:25:09

Makes sense, thanks! Great, simple example. They hold one value, immutably, sounds like.

@sunnyrjuneja 2012-12-13 00:25:52

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]
        @#{attr_name} = value
        @#{attr_name}_history << value

@allenemilyh 2012-12-13 01:10:17

Thank you! Good to know you can change Class, though sounds dangerous! I see that your avatar seems to be doing some monkey-patching...

@AlexChaffee 2012-12-13 01:51:55

In fact, attr_reader and its ilk already support string parameters. Symbols look cooler, though :-)

@Greg Hewgill 2012-12-13 00:21:15

Ruby's attr_accessor, attr_reader, and attr_writer are just shorthand ways of avoiding writing a bit of repetitive code. The following question expands on how these work: Why use Ruby's attr_accessor, attr_reader and attr_writer?

Instead of thinking of attr_reader :book as a variable, just think of it as a name of an attribute that is specified using a symbol.

@allenemilyh 2012-12-13 00:59:49

Thanks! Per the link and other examples I've seen, then, with accessors, symbols point to instance variables, typically. (Helps address my "scope" question above, even if the symbols aren't the variables but just point to the variables.)

@Greg Hewgill 2012-12-13 01:03:57

I don't know that I would go that far - symbols by themselves don't "point" to anything in particular. They are just a way of specifying the name of something, without using a string. In this case it's up to the class methods such as attr_accessor to interpret the symbol as representing the name of an instance variable.

Related Questions

Sponsored Content

33 Answered Questions

[SOLVED] How to check if a variable is set in Bash?

  • 2010-08-30 14:54:38
  • prosseek
  • 1321608 View
  • 1567 Score
  • 33 Answer
  • Tags:   bash shell variables

26 Answered Questions

[SOLVED] JavaScript check if variable exists (is defined/initialized)

20 Answered Questions

[SOLVED] Reference — What does this symbol mean in PHP?

26 Answered Questions

[SOLVED] What is the scope of variables in JavaScript?

30 Answered Questions

[SOLVED] How can I determine if a variable is 'undefined' or 'null'?

19 Answered Questions

[SOLVED] What is attr_accessor in Ruby?

  • 2010-12-06 21:07:06
  • dennismonsewicz
  • 463646 View
  • 1023 Score
  • 19 Answer
  • Tags:   ruby

26 Answered Questions

[SOLVED] How to check if a value exists in an array in Ruby

  • 2009-12-31 17:49:03
  • user211662
  • 872749 View
  • 1315 Score
  • 26 Answer
  • Tags:   ruby arrays

24 Answered Questions

[SOLVED] How to write a switch statement in Ruby

6 Answered Questions

[SOLVED] Why is it bad style to `rescue Exception => e` in Ruby?

Sponsored Content