Eigenclasses aka metaclasses or singleton classes in Ruby.
Check out the metaclass implementations in other languages for more examples.
Note: This gem was originally written back in 2008. Since then, Ruby has introduced a couple new methods which provide the same functionality as this gem's eigenclass
and edefine_method
methods.
Installation
gem install eigenclass
Requirements
Ruby 1.8.7+
Usage
Everything in Ruby is an object, including classes.
SomeObject = Class.new
Every object has an eigenclass
.
SomeObject.eigenclass #=> #<Class:#<SomeObject:0x007f9611030300>>
The implementation of the eigenclass
method is pretty simple.
class Object
def eigenclass
class << self
self
end
end
end
Evaluating code within an eigenclass
lets us do some cool things like defining class level attributes.
SomeObject.eigenclass_eval do
attr_accessor :example
end
SomeObject.example = :test
SomeObject.example #=> :test
The convenience methods for defining class level methods makes this even easier.
class SomeObject
eattr_accessor :example_accessor
eattr_reader :example_reader
eattr_writer :example_writer
ealias_method :new_example_accessor, :example_accessor
edefine_method(:example_class_method) do
1 + 1
end
end
SomeObject.example_class_method #=> 2
When we extend
modules, we're actually just calling include
on an object's eigenclass
.
SomeObject.eigenclass.included_modules #=> [Eigenclass, Kernel]
Example = Module.new
SomeObject.extend(Example)
SomeObject.eigenclass.included_modules #=> [Example, Eigenclass, Kernel]
A convenience method for viewing an object's extended modules is available for us as well.
SomeObject.extended_modules #=> [Example, Eigenclass, Kernel]
Since all objects have an eigenclass
, we can even define methods for a single instance of a class.
object = SomeObject.new
object.eattr_accessor :example
object.example = :test
object.example #=> :test
other_object = SomeObject.new
other_object.example #=> NoMethodError undefined method `example' for #<SomeObject:0x007fee348dde00>
This is pretty incredible! We can hook in and inject behavior into any and all objects - at runtime!
Ruby is like one big plugin framework - with an awesome standard library and amazing community!
API
All methods defined by this gem are simple delegators to existing methods on the eigenclass
object. The links below redirect to each corresponding method in the standard library documentation.
- ealias_method
- eattr_accessor
- eattr_reader
- eattr_writer
- edefine_method
- eigenclass
- eigenclass_eval
- eigenclass_exec
- extended_modules
Testing
bundle exec rspec
Contributing
- Fork the project.
- Make your feature addition or bug fix.
- Add tests for it. This is important so I don't break it in a future version unintentionally.
- Commit, do not mess with Rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
- Send me a pull request. Bonus points for topic branches.
License
MIT - Copyright © 2008 Sean Huber