13 Object individuation
The chapter centers on Ruby’s object individuation: the idea that individual objects can be given their own behavior instead of always behaving exactly like other instances of the same class. This flexibility is presented as a core Ruby principle with practical benefits, including less duplication, more nimble designs, and stronger metaprogramming possibilities. The text emphasizes that while most Ruby code relies on class-wide behavior, understanding per-object behavior reveals how Ruby really works and ties together features that can otherwise seem separate.
A major focus is on singleton methods and singleton classes, which are where per-object methods actually live. The chapter explains how any object can gain its own methods, how class methods are really singleton methods on class objects, and how opening a singleton class with the special class syntax allows methods and constants to be defined there directly. It also shows how singleton classes participate in method lookup, including how modules can be included into a singleton class and how that changes precedence. The extend method is presented as a concise way to achieve the same effect, adding module behavior to one object at a time rather than to an entire class.
The later part of the chapter turns to the risks and techniques of modifying Ruby’s core classes and modules. It warns that global changes are dangerous because they affect the whole runtime, and illustrates the hazards with examples involving regular expressions and string mutation methods. Safer alternatives are described: additive changes, pass-through overrides that preserve original behavior, per-object changes using extend, and refinements, which scope changes lexically so they do not leak outward. The chapter concludes with BasicObject, showing how its minimal method set makes it useful for highly individualized objects driven by method_missing, as in builder-style APIs and custom DSL-like classes that define their own behavior from scratch.
Method-search order, revised to include singleton classes.
Relationships among classes in an inheritance relationship and their singleton classes
Summary
- Singleton classes are where singleton methods live.
- A singleton class can include modules, which get added to the method lookup path.
- Kernel#extend includes a module in an object’s singleton class.
- Class methods are fundamentally singleton methods on class objects.
- When a class inherits, its singleton class inherits from the parent’s singleton class.
- Changes to the behavior of core classes and instances has to be done with care.
- Techniques for core changes include additive overrides, pass-through overrides, the use of extend, and Refinements.
- BasicObject offers a kind of blank slate for designing classes when you need behavior that’s even more “vanilla” than instances of Object.
FAQ
What is object individuation in Ruby?
Object individuation is Ruby’s ability to let individual objects behave differently from other objects of the same class. It means you can add behavior to one object without changing every instance of its class.What is a singleton method?
A singleton method is a method defined for one specific object only. Other objects of the same class do not get that method unless they are individually modified too.What is a singleton class?
A singleton class is the anonymous class that stores an object’s singleton methods. Every object has its normal class and also a singleton class that can hold per-object behavior.How do you define a method in an object’s singleton class?
You can open the singleton class withclass << object and define methods inside it. Any method defined there becomes a singleton method of that object.How are class methods related to singleton methods?
In Ruby, many class methods are really singleton methods defined on class objects. Since classes are objects too, adding a method to a class object creates a class method.What does the extend method do?
extend mixes a module into a single object’s singleton class. This gives that one object the module’s instance methods, which is a common way to add per-object behavior.Why is changing Ruby core classes considered risky?
Changing core classes affects the entire program and can break Ruby itself or other libraries. A method override may alter expected return values or behavior everywhere the method is used.What is the difference between additive changes and pass-through overrides?
An additive change adds a new method that did not previously exist. A pass-through override replaces an existing method but still calls the original version, usually withsuper or an alias, to preserve base behavior.What are refinements used for?
Refinements provide a limited-scope way to modify class behavior. They let you apply changes only within a specific class, module, or file scope instead of affecting the whole program globally.Why is BasicObject useful for object individuation?
BasicObject has very few built-in methods, so it gives you a minimal starting point for creating highly customized objects. It is especially useful when you want to rely on method_missing and avoid conflicts with existing behavior.
The Well-Grounded Rubyist, Fourth Edition ebook for free