This discussion on Hacker News the other day got me thinking about design patterns. I'd already known that I wasn't likely to write crap like this when programming in Ruby, but the discussion got me thinking about common patterns I that I do find myself using in Ruby, and how I could abstract them. The result of that thinking is this set of abominations. Its highlights include:
Bignum#to_fixnum: This will truncate a
Bignuminto a (signed)
Module#after: You can do in your class definition, for example,
before :initialize do puts "initializing! end. This is useful. It'll work even if you haven't defined
klassis a metaclass of
Abominations::DelayMetaclassEval: Including this mixin into your mixin overrides its metaclass's metaclass's
class_eval(yes!) such that any blocks you pass to its metaclass's
class_evalwill be evaluated in the context of the metaclass of the class into which you are mixing your mixin. This means that it's very easy for your mixin to give class methods to the classes into which it is mixed. I've also constructed
Module#afterin such a way that, if you call them in a mixin which includes
Abominations::DelayMetaclassEval, you can do
before :initialize do puts "foo" endin your mixin, and instances of classes into which it is mixed will print "foo" to the screen just before they are initialized, even if
initializeis defined inside the class (not your mixin), even if it's defined after your mixin is mixed in!
This code also does a lot more than this, but it'd really take too long to list everything that it does. It's nearly all monkey patching, so if you're offended by monkey patching then you might want to leave now. Otherwise, take a look at the code and check out everything it does!