Ruby 2.0 : Module#refine

We already talked about Module#prepend as one of the new features of the upcoming Ruby 2.0… Today, let's talk about refinements. Refinements had landed into trunk, but is actually reviewed. It could eventually be reverted for performance issues.

Why refinements

Because Monkey patching: Monkey patching is a powerful feature, but as everybody knows, with great power comes great responsibility. Refinements intend to give you the power of Monkey patching, but without messing with the whole universe of the Ruby runtime.


module FooBar
  refine String do
    def hello
      puts "#{self} says : Hello, world"

class Bar
  using FooBar
  attr_reader :user

  def initialize(user)
    @user = user

  def say

In the module FooBar, we use the class method refine to enhance the class String. And in the class Bar, we declare that we want to use FooBar with the using methods.

Running this code with Ruby 2.0 outputs the following:

af83 says : Hello, world
refinements.rb:23:in `<main>': undefined method `say' for "":String (NoMethodError)`'`

What's happening here

When we call'af83').say, the addition of the method hello on the class String is only effective in the context of the Bar class, thanks to the use of using FooBar.

On the contrary, has no knowledge of the method say. Hence, the NoMethodError.

Like I said, safer monkey patching. :)


You can read the whole story of refinements in Ruby.

Coming next in this series: Enumerator::Lazy.

blog comments powered by Disqus