Sunday, July 20, 2014

Ruby Metaprogramming: class_eval

Lately I've been looking into ways of DRY-ing up ruby classes. One of the first, and perhaps most scarily powerful, is the class_eval method.

What does it do?

class_eval takes in a block or a string and executes it at the class-level. It's that simple!

Is it useful?

Yeah, it's scary useful. Here's an example where I define a bunch of similar methods on a class:

class Person
  ['age', 'name', 'favorite_color'].each do |attribute|
    ['with', 'and'].each do |prefix|
      class_eval %Q(
        def #{prefix}_#{attribute}(value)
          @#{attribute} = value
          self
        end
      )
    end
  end

  def to_s
    "Name: #@name, Age: #@age, Favorite Color: #@favorite_color"
  end
end

me = Person.new.
  with_name('Michael').
  and_age(22).
  and_favorite_color('Blue')

puts me.to_s # => Name: Michael, Age: 22, Favorite Color: Blue

This short little example used class_eval to define 6 methods on the person class: with_age, and_age, with_name, and_name, with_favorite_color and and_favorite_color! Pretty cool, huh?

No comments:

Post a Comment