Wednesday, September 17, 2008

Monkey-Patch Which Prohibits Monkey-Patching

Harkening back to the blog hubbub about anti-monkey-patching, Garry Dolley created a monkey-patch which makes monkey-patching impossible.

Ruby provides a method_added() callback that is invoked every time a method is added or redefined within a class. It’s part of the Module class, and every Class is a Module. There are also two related callbacks called method_removed() and method_undefined().

This means you could detect when other code has redefined a method, and do something about it! How about redefining that method (again) to point back to your original code? Indeed, this works.

I’ve encapsulated the details of this in a new module I call Immutable. It provides one class method called immutable_method(). Provide it a list of methods you don’t want touched and it’ll make sure they can’t be redefined. Hence, immutable.

I'm not saying this is a sane thing to do. But I think it's interesting. I work with Garry - he works for a company my company builds software for - so I'm going to bring this up in real life, but just for the record, one thing which makes me question the security of the whole shebang is that Immutable doesn't raise errors if you redefine a method and it blocks your redefinition. Method definition confusion drove the whole discussion in the first place, and here we have a solution which at the same time both prevents the problem, and guarantees that it will happen.