Thursday, June 14, 2007

Again, reopen with class_eval/module_eval!

I've written about this before, but it bit my team again today, so I think it bears repeating: If you want to get inside someone else's class (or one of your own classes from someplace funny, like a unit test), and particularly if you're running in a Rails environment (i.e., a world of const_missing magic that auto-requires files), don't use the ambiguous but pretty approach:

class SomeLibraryThingy
  def stuff_thing
    ...
  end
end 

You might discover the class you're trying to re-open hasn't been loaded yet. Sacrifice a smidgen of lovely in favor of certainty:

SomeLibraryThingy.class_eval do
  def stuff_thing
    ...
  end
  # or
  define_method :stuff_thing do
    ...
  end
end

You'll save yourself a confusing few minutes of NoMethodErrors and other bizarrerdry.

2 comments:

Herval said...

great tip, thanks! :)

nikolasco said...

It's worth noting that define_method adds significant overhead to the created method; def is always faster ...