Search code examples
ruby-on-railsrubyerbmonkeypatching

Monkey patching scope: Outside function doesn't affect ERB


I'm trying to patch some I18n methods to test correct escaping. Doing this in a test, and it goes something like:

test "JS files should be using correct escaping" do
  module I18n
    def self.t(*args)
      %q{a JS interpolation ' " test}
    end
  end
  filename = Rails.root + "app/assets/some_file.js.erb"
  erb = ERB.new(File.read(filename))
  result = erb.run
end

At this point, all of the I18n.t calls within some_file.js.erb are indeed replaced... but with correct values from the I18n files, not with a JS interpolation ' " test.

In other words, the monkey patch doesn't take hold inside of ERB. Is there a way for me to make this work?


Solution

  • I'd guess that your module I18n isn't actually opening ::I18n, that's probably executed in an unexpected context so you're actually opening the SomethingUnexpected::I18n module for some SomethingUnexpected that's part of the test framework.

    The easiest way around that is to explicitly state that you want to work in the top level namespace:

    module ::I18n
      #...
    end