This is a read-only archive!

Ruby singleton classes

I was writing some Ruby and I must've had my head stuck in Java, because I wrote something like this:

class Test1
    @x = 1
end

That is very different from this:

class Test2
    def initialize
        @x = 1
    end
end

In the latter case I made a normal instance variable which any object that is_a? Test2 can access. In the former case I made an instance variable of Test1 itself. Classes in Ruby are Objects like any other; I gave the Test1 object itself an instance variable. So:

Test1.new.instance_variables # => []
Test2.new.instance_variables # => ["@x"]

Chapter 24 of the Pickaxe book talks about singleton classes. You can edit objects (add methods and instance variables etc.) on a per-object basis rather than a per-class basis. You can do this because Ruby makes a "virtual" singleton class, makes that singleton class the direct class of your object, and makes your object's original class the superclass of this new singleton class. That way the object's original class is untouched and your meddling doesn't affect any other objects of the same class.

In Test1 above this is what I did. Ruby made a new singleton class, which the Pickaxe calls Test1, and made an instance variable @x in it. That instance variable is then accessible as a part of the Test1 object itself. If it were theoretically possible to instantiate another object of type Test1', it would presumably have a @x too, but this isn't possible.

So say I want to access this @x that belongs to Test1. The Pickaxe tells you how. In general, if you have an object and you want to access an instance variable of it, you define a "getter" method in your object's class that returns the variable's value. You can use the shortcut attr_reader to do this.

So if you want to access an instance variable of Test1 itself, you need to define a method in Test1's class (i.e. the singleton class, Test1'). The Pickaxe says to do this:

class Test1
    class << self
        attr_reader :x
    end
end

Test1.x  # =>; 1

It makes perfect sense that you can also do it this way:

class << Test1
    attr_reader :x
end

Test1.x  # => 1

The Pickaxe gives a couple reasons why you might want to do this kind of thing. But I'm going to go ahead and label it "black magic" and stay away from it, I think.

March 22, 2007 @ 3:26 AM PDT
Cateogory: Programming
Tags: Ruby

4 Comments

markus
Quoth markus on May 16, 2008 @ 7:01 AM PDT

wow

late but cool i never knew this :-)

btw your << appear wrong in the code

Brian
Quoth Brian on May 16, 2008 @ 9:40 AM PDT

Oops, must've changed my blog-post bracket-escaping code a while back. I fixed it.

Peregrinati
Quoth Peregrinati on August 06, 2008 @ 1:37 PM PDT

I'm just learning Ruby now, and I'm struggling with the code:

class << self #... end

that I keep seeing everywhere as I try to learn about singleton and class methods. What does the '<<' "Operator" (method?) actually do?

Brian
Quoth Brian on August 06, 2008 @ 2:00 PM PDT

I'm unsure that << in the case of "class << something" is actually a method. It may be a special operator. Regardless, it's an idiom you pretty much have to memorize. It's not very intuitive at a glance. It means "start a new scope where things inside like def etc. operate on self's singleton class". A singleton class is a class that applies only to a specific single object. It's also sometimes called a metaclass or any number of other terms.