Home » Code, Headline

Excessive (ab)use of eval (try send instead)

23 July 2009 Comments

I was just reminded how much I have learned about Ruby metaprogramming in just the past few months when I looked back at the original code I wrote for the soundex_find plugin. The code worked great, but relied on excessive eval calls:

def update_soundex
  eval("#{self.class}").sdx_columns.each {|c|
    eval("self.#{c}_soundex = #{self.class}.soundex(self.#{c})")
  }
end

Which I rewrote to use zero evals:

def update_soundex
  self.class.sdx_columns.each {|c|
    self.send("#{c}_soundex=", self.class.soundex(self.send(c)))
  }
end

How did I come up with the first version?

  • I didn’t realize object.class returns a Constant which can be used to directly call class methods. (I thought it returned a string.)
  • I didn’t understand the power of object.send, which allows methods to be called using strings.

I’m sure if I come back to this in another six months, I’ll find a way to improve it again.

Photo credit: Kitty de Medici

blog comments powered by Disqus