Monkey patching’s main issue is that it pollutes the global scope. Your code working is at the mercy of all the modules you use not stepping on each others toes. The Ruby solution to this is refinements, which are basically monkey patches in a limited scope.
module Patches
  refine Fixnum do
    def plus_one
      self + 1
    end
    def plus(num)
      self + num
    end
    def concat_one
      self.to_s + '1'
    end
  end
end
class RefinementTest
  # has access to our patches
  using Patches
  def initialize
    puts 1.plus_one
    puts 3.concat_one
  end
end
# Main scope doesn't have changes
1.plus_one
# => undefined method `plus_one' for 1:Fixnum (NoMethodError)
RefinementTest.new
# => 2
# => '31'