-
Ruby 1.9 broke your ish…
Ruby 1.9 has been here for a minute now. If you’re not already using it in production, get ready to because Rails, that opinionated little bugger, really wants you to use it with 3.0
I’m sure you have seen this pattern for extending objects with your own functionality before:
module IncredibleFunctionality def wozers # Your insanely great code here… end end ActiveRecord::Base.send :include, IncredibleFunctionalitySlow down fast lane
irb(main):001:0> Module.private_method_defined? :include
=> trueThis will blow up in your face with Ruby 1.9.
includeis a private method of Module and you can no longer usesendto externally call private methods on an object in 1.9.Great. So what are our options?
Open the class:
class ActiveRecord::Base def wozers # Your insanely great code here… end endYuck. Or slightly better:
module IncredibleFunctionality def wozers # Your insanely great code here… end end class ActiveRecord::Base include IncredibleFunctionality endTo me this is insanely horrible. There might be nothing wrong with this, but this just smells to me, from an aesthetic point at the very least. If it could be done in one line AND in a readble, sensible way before, that’s the way I want to do it now too.
HACK AWAY:
module IncredibleFunctionality def wozers # Your insanely great code here… end end ActiveRecord::Base.__send! :include, IncredibleFunctionalityYou can continue to use send to call private methods using
__send!Although for me, it’s anathema to continue something that the Ruby maintainers thought badly enough of to change the API.Also worth mentioning that
__send!is new for 1.9. so this will not work on the 1.8 branch, which makes this method kind of useless if you’re hoping that a lot of people might use your code.class_eval:
module IncredibleFunctionality def wozers # Your insanely great code here… end end ActiveRecord::Base.class_eval { include IncredibleFunctionality }Sets the context of self in the block to the receiver. Allows us to call include with the implicit receiver being that of the object we wish to extend.
WIN!
These are the ways I’ve come up with to work around this issue. What are yours?
Mon25Jan