Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Makes methods 'invincible', and their implementations stackable
Ruby C
Branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.



Refinery stemmed from a very specific need that arose while writing attr_* — to be able to utilize the Ruby hooks (for example, the method_added and method_missing methods) without “gobbling them up” so to speak. Normally, had I used those methods (especially if my particular implementation was very dependent on these methods operating in a specific way), the person using my library would be precluded from using the same methods in whatever class they included/extended my library into; if they used one of those methods for some purpose, their definition would ‘overwrite’ mine, thus quite possibly making my library (or their code using my library) cease to function correctly.

The simple, singular purpose of Refinery is to ‘refine’ methods in such a way that your important functionality can be assigned safely to these methods. Any attempts to re-define a ‘refined’ method after the refining process will simply ‘stack’ with your own implementation — your method code will execute first, with further re-definitions each being executed in turn when the method is called.


Using Refinery is very simple - extend it into your class (or include it into the Class class if you use it often), and then pass a method's name (as a symbol) to the refine_method singleton method. A short example:

class Something
  extend Refinery

  def method_missing meth, *args
    # Do some magic!
    puts 'abc'

  refine_method :method_missing

# Later, somewhere else…

class Nothing < Something
  def method_missing meth, *args
    # Do other magic, not knowing about the former magic!
    puts 'def'

nothing =

Once refined, any further re-openings of your class (or a descendant) and re-definitions of the refined method will simply result in the implementations 'stacking' with eachother.

Care must obviously still be taken to ensure your code will 'stack' in a friendly way with the other implementations — be sure to programmatically check whatever may be necessary before executing your method's code!


You can install Refinery as a pre-built gem, or as a gem generated directly from the source.

The easiest way to install Refinery is to use RubyGems to acquire the latest 'release' version from RubyForge, using the gem command line tool:

sudo gem install refinery # You'll be asked for your account password.

Alternatively, you can acquire it (possibly slightly more up-to-date, depending on how often I update the gemspec) from GitHub as follows:

# If you've ever done this before, you don't need to do it now - see
gem sources -a
sudo gem install elliottcable-refinery # You'll be asked for your account password.

Finally, you can build a gem from the latest source yourself. You need git, as well as [rake][]:

git clone git://
cd refinery
# If you've ever done this before, you don't need to do it now - see
gem sources -a
sudo gem install elliottcable-echoe # You'll be asked for your account password.
rake install # You'll be asked for your account password.


You can contribute bug fixes or new features to Refinery by forking the project on GitHub (you'll need to register for an account first), and sending me a pull request once you've committed your changes.


  • GitHub is the project's primary repository host, and currently also the project's home page
  • RubyForge is out primary RubyGem host, as well as an alternative repository host
  • integrity is out continuous integration server - if the top build on that page is green, you can assume the latest git HEAD is safe to run/install/utilize.
  • Gitorious is an alternative repository host
  • is an alternative repository host


The Sing extension was contributed by John Mair.


Refinery is copyright 2008 by elliott cable.

Refinery is released under the GNU General Public License v3.0, which allows you to freely utilize, modify, and distribute all Refinery's source code (subject to the terms of the aforementioned license).

Something went wrong with that request. Please try again.