labs ruby scala

Failed attempt at trying to use refinements

I was pretty interested in refinements in Ruby 2.0, and after listening to the latest Ruby Rouges podcast where some serious doubts were raised about the viability of refinements I thought I’d build a little example of how I was thinking I could use it.

I failed first time out and I tried copying and pasting examples without success. After some time poking around I found a blog post about why this wasn’t working. Ultimately, refinements are sort of left in the language, but not fully supported and are marked as experimental.

Here’s what I wanted to achieve. Coming from Scala in my previous job, I thought I could use refinements as a proxy for implicit conversions. Here I refine the Fixnum class to allow it to respond to a to_currency message. When called it converts the Fixnum instance to a Currency instance.

class Currency
  attr_reader :units

  def initialize units
    @units = units
  end
end

module CurrencyExtensions
  refine Fixnum do
    def to_currency
      Currency.new(self)
    end
  end
end

class App
  using CurrencyExtensions

  def initialize
    puts 3.to_currency
  end
end

App.new

Why is this interesting to me? Well, I think being able to write 3.to_currency can result in nicer to read code than the alternative Currency.new(3). Small difference perhaps.

There is a way to get this to work by having the using keyword in the global context, but it doesn’t deliver the full impact I was hoping for.

class Currency
  attr_reader :units

  def initialize units
    @units = units
  end
end

module CurrencyExtensions
  refine Fixnum do
    def to_currency
      Currency.new(self)
    end
  end
end

using CurrencyExtensions
puts 3.to_currency

I’ve got other ideas to build upon this if it ever makes it into the full specification. I’ll keep watching for now.