Save keystrokes with generated initializers!

This article is quite old.Time flies when you're having fun. I've been writing for my blog for a long time. Stuff changes fast, especially in the Ruby world. That's why I've put this warning on old posts. The article might still be valid, though.

Monkey Patch of the Month: attr_initializer

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!

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
comments powered byDisqus