Search code examples
rubymonkeypatchingruby-1.9.3

How to use Ruby Module?


The following code works fine:

class Float
  def round
   self.format.to_f
  end

  def format
    "%.2f" % self
  end
end

However, it seems bad practice to monkeypatch a class like Float because other people are doing the same thing and it causes problems.

Then I installed simplecov and the problem started: simplecov monkeypatches the same methods.

So I created a module and mixed it in to Float.

module MyModule
  def round
   self.format.to_f
  end

  def format
    "%.2f" % self
  end
end

Which I guess works as well. But the problem is that simplecov seems to be overwriting the mixed-in method above.

So, what is the proper way to extend built-in classes so that they do not conflict with other people's code?

Ruby 1.9.3


Solution

  • Why not use just argument on the round call?

    13.6657.round(2)    # => 13.67
    

    But if you are sure you need module (to possibly adjust the format for all Floats out there, I'd propose you just define format method as such:

    module MyModule
      def format
        ("%.2f" % self).to_f
      end
    end
    

    And mix this in to Float. And later in code you call the format method instead of round:

    13.6657.format     # => 13.67
    

    This way it does not hurt the core functionality (as your initial code dropped the argument from the round definition).

    Even better - if you want (can) pinpoint the monkey-patching, simply extend specific instance:

    a = 13.6657
    a.extend MyModule
    
    a.format           # => 13.67
    

    This way it wont mess with other Floats, but you can still adjust the format without finding all calls to a.round(2) in your code.