0

I would like to know how properly monkey patch a core DSL on RoR. I have the following monkey patch:

# frozen_string_literal: true

module CoreExtensions
  module Numeric
    def percent_of(number)
      to_f / number * 100.0
    end
  end
end

(I've followed this article).

Now I would like to know where to put the following:

Numeric.include CoreExtensions::Numeric

I would like to have this percent_of method available for all my app. I've tried to place it in config/application.rb:

# frozen_string_literal: true

Rails.application.configure do
 # ...
end

Numeric.include CoreExtensions::Numeric

But it didn't work. When I try to serve the following error is raised:

uninitialized constant CoreExtensions (NameError)

Thank you.

Amanda Ferrari
  • 1,168
  • 5
  • 17
  • 30
  • What is the path to the core extensions file? – rossta Dec 30 '19 at 12:16
  • You can place your monkeypatch in a file in the 'config/initalializers' directory. It will be required during the initialization phase. – max Dec 30 '19 at 12:24
  • Since you are not using refinements, what would be wrong with just reopening and altering the class? Why would you ever need to declare a custom module and include it? – Aleksei Matiushkin Dec 30 '19 at 12:27
  • To expand on @AlekseiMatiushkin's suggestion, you can "reopen" the module in Ruby using the same syntax you would use to create a new module: module Numeric; def percent_of(number); to_f / number * 100.0; end; end – Keith Bennett Dec 30 '19 at 13:06
  • @KeithBennett `Numeric` is a class, not a module. – Aleksei Matiushkin Dec 30 '19 at 13:34
  • Does this answer your question? [In Ruby on Rails, to extend the String class, where should the code be put in?](https://stackoverflow.com/questions/5654517/in-ruby-on-rails-to-extend-the-string-class-where-should-the-code-be-put-in) – Mosaaleb Dec 30 '19 at 17:07

2 Answers2

2

As max commented, you can use Rails initializers folder for monkey patching the libraries.

I would suggest creating a new folder core_extensions within config/initializers/ and group patches related to the same module/class in a separate file and place the include at the last line.

## File path: config/initializers/core_extensions/numeric.rb

# frozen_string_literal: true

module CoreExtensions
  module Numeric
    def percent_of(number)
      to_f / number * 100.0
    end
  end
end

Numeric.include CoreExtensions::Numeric
Prabakaran
  • 355
  • 2
  • 10
0

I created a file in lib/extensions/ & called it numeric_ext.rb with this content:

class Numeric
  def percent_of(number)
   to_f / number * 100.0
  end
end

After that I included this snippet in my application.rb

config.to_prepare do
  load 'extensions/numeric_ext.rb'
end

I tested this & It's working properly.

Bisher
  • 141
  • 6