Monkey-patch without making a mess

class Fixnum
  # convert minutes to hours in decimal format (75 minutes is 1.25 hours)
  def to_hours
    (self.to_f / 60).round(2)
  end
end

What is Monkey Patching?

  • Alternatives?

Alternatives

  • Inherit class
  • http://ruby-doc.org//core-2.1.2/doc/syntax/refinements_rdoc.html
  • Refinements
class MySexyClass < SuperClass
  def to_hours
    (self.to_f / 60).round(2)
  end
end

MySexyClass.new(125).to_hours

Problems?

  • If two libraries monkey-patch the same method, you won’t be able to tell.
  • If there’s an error, it’ll look like the error happened inside Integer
  • It's hard to turn off you monkey patches
  • If you, say, forgot to require 'integer' before running this monkey patch, you’ll accidentally redefine Integer instead of patching it.

Improvements

lib/core_extensions/integer/hours.rb

module CoreExtensions
  module Integer
    module Hours
      def to_hours
        (self.to_f / 60).round(2)
      end
    end
  end
end
config/initializers/extensions.rb

# Actually monkey-patch Integer
Integer.include CoreExtensions::Integer::Hours
  • Put your monkey patches in a module
  • Load them in one file
  • keep patches together in lib/core_extensions
  • patch smart
  • think through the edge cases

Final thoughts

Monkey Patch

By Jan Varljen

Monkey Patch

  • 675