Adventures with Ruby

Monkey Patch of the Month: attr_initializer

View Comments

So, about one month ago, I promised to share some useful monkey patches every month. Here is the second one. Your own monkey patches are still more than welcome!

Common Squirrel Monkey (from Wikipedia)

I often find myself writing code like this:

class Foo
  attr_reader :bar, :baz
  def initialize(bar, baz)
    @bar, @baz = bar, baz
  end
end

This can be very annoying to maintain. The variable names are repeated four times, within three lines of code!

Ideally, I’d want to write something like this:

class Foo
  attr_initializer :bar, :baz
end

Much better, if you ask me. Here is one example of how to do this.

class Class
  def attr_initializer(*attributes)
    attr_reader *attributes
    class_eval <<-RUBY
      def initialize(#{attributes.join(', ')})
        #{attributes.map{ |attribute"@#{attribute}" }.join(', ')} = #{attributes.join(', ')}
      end
    RUBY
  end
end

No piece of code is complete without tests, so this is it:

class AttrInitializerTests < Test::Unit::TestCase

  def test_attr_initializer
    klass = Class.new do
      attr_initializer :foo, :bar
    end
    object = klass.new(1, 'b')
    assert_equal 1, object.foo
    assert_equal 'b', object.bar
  end
 
end

Written by Iain Hecker

April 12th, 2010 at 7:57 am

Posted in iain.nl

View Comments to 'Monkey Patch of the Month: attr_initializer'

Subscribe to comments with RSS or TrackBack to 'Monkey Patch of the Month: attr_initializer'.

  1. [...] I talked about a monkey patch called attr_initializer, allowing you to write code like [...]

  2. [...] you’re wondering what the attr_initializer is, it’s a monkey patch, that I’ve described here. The delegate-method is something ActiveSupport offers you. Use it, it’s super [...]

Leave a Reply

You must be logged in to post a comment.

blog comments powered by Disqus
Fork me on GitHub