rubyruby-on-rails-5refinements

Refine gem's class method


I have to wrap some behavior around an external gem in a elegant and isolated manner. Given the abstraction below, everything runs smoothly, but 'bar' is never printed. Could someone tell me why?

My code:

module RefineGem
  refine GemMainModule::GemClass do
    def self.foo
      p 'bar'
      super
    end
  end
end

module Test
  using RefineGem

  def test
    GemMainModule::GemClass.foo
  end
end

class Testing
  include Test
end

Testing.new.test

Gem code:

module GemMainModule
  class Base
    include GemMainModule::Fooable
  end

  class GemClass < Base
  end
end

module GemMainModule
  module Fooable
    extend ActiveSupport::Concern

    class_methods do
      def foo
        p 'zoo'
      end
    end
  end
end

Solution

  • I doubt refinements work for class methods. You might refine the singleton_class though:

    module RefineGem
      refine GemMainModule::GemClass.singleton_class do
        def foo
          p 'bar'
          super
        end
      end
    end
    

    I personally prefer to use Module#prepend to achieve the same functionality:

    GemMainModule::GemClass.singleton_class.prepend(Module.new do
      def foo
        p 'bar'
        super
      end
    end)