The naked Ruby: Object specialization with eigenclass

Ruby has this construct that is sometimes called eigenclass or singleton class. No, it’s got nothing to do with the singleton pattern that is familiar to most Java programmers. It is rather a construct that allows a form of object specialization. Let me explain.

One of the fundamental features of an object-oriented programming language is the use of an inheritance construct that allows object classes to be specialized or subtyped. If you were to model various geometrical objects, the class Shape may be used to represent their abstraction. All objects of type Shape has a location and will understand how to move, for example, because Shape holds that location and the implementation of a method called move.

class Shape
    attr_reader :location
    def move(new_location)
        # move the shape somehow
    end
end

A circle is a kind of shape, a special kind of shape, with attributes and behaviors that make it different from other shapes. This specialization relationship is expressed through the subclass construct of the language.

class Circle < Shape
    def roll
        # move the circle by rolling it
    end
end
polka_dot = Circle.new
polka_dot.roll

The eigenclass construct makes possible further specialization of an object. This construct allows an object to have new behaviors that are unique to that particular instance.

class << polka_dot
    def explode
        # explode the polka dot at its current location
    end
end
polka_dot.explode

The above code snippet says, “Object polka_dot, let me access your eigenclass, and let me add this method called explode. Now that you know how to do it, please explode.”

Dog trick

No other circle knows how to explode. Only the polka_dot — a super-specialized instance of Circle — knows how. This means that in Ruby you can easily teach objects new tricks, without requiring other objects of the same type to change.

The benefit of this feature is tremendous.

In other programming languages, I would have to rely on creating a subclass, if allowed, and use a number of unsavory up- and down-casts to do this kind of super-specialization. Or, if the object’s class happens to be specified as final, I would have to resort to the use of containment and delegation — resulting in an incompatible object — to approximate the same effect. Neither approach is an ideal fit for modeling object specialization.

In real life, with some persistence, and the right techniques, I really could teach a dog new tricks. And so, I want my programming language to let me do the same thing with objects.

Comment

Commenting is closed for this article.