Eigenclass in ruby
The concept of eigenclasses in Ruby is a fascinating and somewhat unique aspect of its object model. It’s deeply tied to Ruby’s flexibility with metaprogramming. Let’s break it down step by step so you can understand it thoroughly.
1. What Is an Eigenclass?
An eigenclass (also called a singleton class) is a special, hidden class associated with an object. When you define a method on a single object (rather than its entire class), Ruby creates an eigenclass to hold that method.
Key Points:
- Every Ruby object has its own eigenclass.
- The eigenclass stores methods that are specific to that object.
- Methods in the eigenclass take precedence over methods defined in the object’s regular class.
2. Why Do We Need Eigenclasses?
Eigenclasses enable singleton methods, which are methods that belong to a single object rather than to all instances of a class.
Example:
str = "hello"
def str.shout
self.upcase + "!!!"
end
puts str.shout # "HELLO!!!"
Here’s what happens under the hood:
- Ruby creates an eigenclass for
str
(if it doesn’t already exist). - The method
shout
is added to the eigenclass. - When you call
str.shout
, Ruby looks in the eigenclass first, findsshout
, and executes it.
3. How to Access the Eigenclass?
You can access an object’s eigenclass using the singleton_class
method.
str = "hello"
puts str.singleton_class # => #<Class:#<String:0x00007f9e9b2c3d10>>
# Inspect eigenclass methods
puts str.singleton_class.instance_methods(false) # [:shout]
4. How Do Eigenclasses Fit in the Lookup Chain?
When Ruby looks up a method, it searches in this order:
- The eigenclass of the object.
- The class of the object.
- Any modules included in the class.
- Superclasses and their eigenclasses/modules, up the inheritance chain.
This means methods in the eigenclass take priority over methods in the regular class or modules.
Example:
class Person
def greet
"Hello!"
end
end
john = Person.new
def john.greet
"Hi!"
endputs john.greet # "Hi!" (from eigenclass)
5. Eigenclasses for Classes (Metaclasses)
Classes themselves are objects in Ruby, which means they also have eigenclasses.
Example:
class Dog
end
def Dog.speak
"Woof!"
endputs Dog.speak # "Woof!"
Here’s what happens:
Dog
is an object of the classClass
.- Ruby creates an eigenclass for
Dog
. - The method
speak
is added to the eigenclass ofDog
.
Visualizing the Hierarchy:
Dog (an object of Class)
└── Eigenclass of Dog
└── Class (the parent class of Dog)
└── Eigenclass of Class
└── Module
6. Open Up the Eigenclass Explicitly
You can explicitly open an object’s eigenclass using class << object
syntax:
Example:
class Person
end
person = Person.newclass << person
def greet
"Hello from the eigenclass!"
end
endputs person.greet # "Hello from the eigenclass!"
Here:
class << person
opens up the eigenclass ofperson
, allowing you to define methods directly on it.
7. Practical Use Cases for Eigenclasses
Singleton Methods:
Used for defining behavior specific to a single object.
logger = Logger.new(STDOUT)
def logger.debug_mode
self.level = Logger::DEBUG
end
logger.debug_mode
Class Methods:
Class methods are stored in the eigenclass of the class.
class Animal
def self.kingdom
"Animalia"
end
end
puts Animal.kingdom # "Animalia"
Here, self.kingdom
is stored in the eigenclass of Animal
.
Metaprogramming:
Used for advanced metaprogramming techniques where you dynamically add methods or behavior.
8. Inspecting and Debugging Eigenclasses
You can inspect and debug eigenclasses using:
singleton_class
singleton_methods
methods
andinstance_methods
Example:
obj = "Ruby"
def obj.unique_method
"I'm unique!"
end
puts obj.singleton_methods # [:unique_method]
puts obj.singleton_class # #<Class:#<String:0x00007fae8913b810>>
puts obj.singleton_class.ancestors
Summary
- Eigenclasses are a key part of Ruby’s object model, enabling singleton methods and class-specific behavior.
- They’re automatically created when you define a method on an individual object.
- You can explicitly access or modify them using
singleton_class
orclass << object
. - They’re essential for metaprogramming and understanding the method lookup chain.