Override a method inside a gem from another gem

后端 未结 2 368
刺人心
刺人心 2021-01-20 16:24

Ok, I have a rails gem that I am working on and I want it to override a specific method in sprockets.

The method I want to override is: Sprockets::Base.digest so tha

相关标签:
2条回答
  • 2021-01-20 16:55

    It's impossible to override an entire Ruby class in that manner, but I think it is possible to prevent the original class from loading...if it's using autoload. I was curious, so I checked out https://github.com/sstephenson/sprockets/blob/master/lib/sprockets.rb, and yes, Sprockets is using autoload.

    autoload :Base, "sprockets/base"
    

    Importantly, that doesn't load the code. It simply tells Ruby that if/when an undefined constant called "Sprockets::Base" is ever encountered, to load it from the specified file. Your patch defines Sprockets::Base before it is ever called anywhere, thus preventing the original file from loading.

    When you moved your patch to the Rakefile, something in Rails had already referenced Sprockets::Base, loading the original code. Your patch then applied cleanly on top.

    I've never actually used autoload, so I'm not sure how cases like this are supposed to be handled. I'm betting though, that this would work:

    Sprockets::Base
    class Sprockets::Base
      def digest
    ...
    

    By referencing the class first, you should force Ruby to load the original class. Then you can safely go about the business of overriding one of its methods.

    0 讨论(0)
  • 2021-01-20 17:06

    Ok, I marked your answer correct, but it really only led me to figure out the problem.

    Anyway, the rails app was requiring my base file instead of the one in the gem itself. Which is what you said. However, the reason it was happening seems to have been caused by the path itself. The path to the file was basically the same as the gem's (lib/sprockets/base.rb).

    Moving that file into my gem's "namespace" (lib/my_gem instead of lib/sprockets) and renaming it to sprockets_base.rb fixed the problem! Weird, huh?

    In other words, me trying to keep the directory structure nice actually seems to have confused Rails into thinking it was the gem itself or something.

    0 讨论(0)
提交回复
热议问题