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.
About the Author
BiographyMore Content by Robbie Clutton