Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Add additional functionality to objects.
Latest commit 51c15ba @steveklabnik Merge pull request #2 from yaauie/feature/multi-becomings-and-unbecom…

allow multiple becomings on a single object; add unbecoming


Have you ever used delegation libraries, but found them a bit unsatisfactory? Delegation is awesome, but many Ruby libraries love their metaprogramming, and so they expect class names to match up. This often screws up delegation.

Becoming allows your objects to have 'becomings' that make them have extended functionality. They still have the same class as they did before, but now they're just... different.


Add this line to your application's Gemfile:

gem 'becoming'

And then execute:

$ bundle

Or install it yourself as:

$ gem install becoming


For example, let's imagine you're writing a Rails form:

# a model that looks like this
User =, :last_name)

# in the controller
@user ="Steve", "Klabnik")

# in the view
<%= form_for @user do |f| %>

This does reflection on the class of the @user, generating HTML like this:

<form action="/users/1">

This is mega awesome. But, let's say that we want to add some new presentation methods on our User. So we make a class:

class FullNameUser
  def initialize(user)
    @user = user

  def full_name
    "#{@user.first_name} #{@user.last_name}"

  def method_missing(m, *args, &blk)
    @user.send(m, *args, &blk)

We update our controller to use this new object:

user ="Steve", "Klabnik")
@user =

Now, our form... does the wrong thing:

<form action="/full_name_users/1">

Drat! So what do we do?

Answer: make your object have a becoming:

# in the model
User =, :last_name) do
  include Becoming

# your 'decorator'
module FullNamed
  def full_name
    "#{first_name} #{last_name}"

# in the controller
@user ="Steve", "Klabnik")

Now, your form will generate the same HTML as before, and everything is just peachy.

How does it work?


Is it any good?


What's the catch?

You can only use this with Ruby 2.0, sorry.


  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request


Shout-outs go to Avdi Grimm, Gilles Deleuze, and Felix Guattari. Without them, this gem wouldn't exist.

Avdi for the excellent Ruby Tapas, on which Episode 91 became the basis for the code in this gem.

D&G for making me moderatly obsessed with the idea of OOO where objects turn into other objects. Also the name.

Something went wrong with that request. Please try again.