Override a method inside a gem from another gem
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.
Overriding a module method from a gem in Rails
What you are doing will work, but your code needs to look like this:
module WillPaginate
module Finder
module ClassMethods
def paginate_by_sql(sql, options)
# your code here
end
end
end
end
In other words, go into finder.rb, delete everything except the module headers and the method you want to override, then save to a file in lib and include in environment.rb. Voila, instant monkey patch!
How to override a method of a class from a gem in Rails?
Create a .rb file in config/initializers
directory with the following code:
Youtube::Display.class_eval do
def find(id, options = {})
# Code here
end
end
Override initialize method of a gem?
Instead of overwriting the method, you can move your custom implementation into a separate module and prepend
it to the Queue
class:
# config/initializers/queue_extension.rb
module QueueExtension
def initialize(name, redis_or_options = {})
# Custom logic
super # <- as needed, invokes the original Redis::Unique::Queue#initialize
end
end
Redis::Unique::Queue.prepend(QueueExtension)
Using prepend
puts the code "in front" of the existing code.
If Redis::Unique::Queue
is not available at that point, you might have to require
it.
How can one override a class method inside a module inside a gem?
Try
OmniAuth::Configuration.class_eval do
def add_camelization(name, camelized)
...
end
end
Overwriting a dependency gem class which inherits from a parent class
No, you can't actually change the parent class without basically rewriting the subclass. If you only have two methods in each class that's probably fine, but Ruby classes use single-inheritance, so you can't re-assign a subclass to a different superclass without redefining it. You can, however, do any of the following:
- Re-open the class and redefine its methods.
- Prepend a module to redefine the behavior of existing methods.
- Add or modify methods for the singleton class, or on a singleton instance of that class.
- If your class is inheriting from Delegator, you can change the delegate class with #__setobj__.
Since you haven't really defined a use case, it's hard to tell which method would be best for you. Once the parent class is defined, though, it stays defined, so you'll have to do whatever you're trying to do another way.
Related Topics
Display Result Data Without Page Refresh on Form Submission in Ruby on Rails
How to Access HTML Elements That Are Rendered in JavaScript Using Xpath
What Is an Eoferror in Ruby File I/O
Defined' and 'Unless' Not Working as Expected
Why Can't We Override '||' and '&&'
How to Split String into 2 Parts After Certain Position
Rails: Organizing Models in Subfolders Having Warning: Toplevel Constant a Referenced by B::A
Does 'Upcase!' Not Mutate a Variable in Ruby
How to Add Iedriverserver to Path
Actionmailer Smtp "Certificate Verify Failed"
Rails: Merit Gem Badge Not Registering or Displaying
Ruby Daemon Process to Keep Objects Alive for Transient Ruby Instances
Currying a Proc with Keyword Arguments in Ruby
Use [].Replace to Make a Copy of an Array
Validates Presense VS Null False in Rails Models/Tables
Undefined Method Error When Creating Delayed_Job Workers with Script/Delay_Job