eigenclass -

Eigenclasses (aka metaclasses or singleton classes) in ruby.

Check out the implementations for metaclasses in other languages for more examples.

Note: This gem was originally written back in 2009. 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

Usage

Everything in Ruby is an object, including classes.

class SomeObject
end

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 the context of an object's eigenclass allows us to do some pretty cool things like defining class level attributes.

SomeObject.eigenclass_eval do
attr_accessor :testing
end

SomeObject.testing = :example
SomeObject.testing #=> :example

The convenience methods for defining class level methods makes this even easier.

class SomeObject
eattr_accessor :test_accessor
eattr_reader :test_reader
eattr_writer :test_writer

edefine_method(:test_class_method) do
  :test_define
end
end

SomeObject.test_class_method #=> :test_define

Since all objects have an eigenclass, we can even define methods on individual instances of a class.

object = SomeObject.new
object.eattr_accessor :example
object.example = "cool"
object.example #=> cool

other_object = SomeObject.new
other_object.example #=> NoMethodError undefined method `example' for #<SomeObject:0x007fee348dde00>

This is pretty incredible! Ruby is like one big plugin framework - with an awesome standard library!

API

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.