Reputation: 263
Is it possible to dynamically override a class method in Ruby?
I have a ErrorHandler
module which should dynamically create a class method with a given name and do the same as the method it is overriding:
module ErrorHandler
def self.handle_error_from(method_name)
define_singleton_method(method_name) do |*arguments|
begin
super(*arguments)
rescue
return "Handler return"
end
end
end
end
The above module is prepended
to another module.
module AnotherModule
prepend ErrorHandler
ErrorHandler.handle_error_from :create
def self.create(params)
# Code here
end
end
The above example triggers the ErrorHandler but it does not override it with the created method.
I've seen this be done with instance methods, but is there a limitation when it is class methods?
Upvotes: 1
Views: 614
Reputation: 2187
You have a few errors in your code.
With prepend
and self
in your module you will actually define the wrapper method on your module. You can try this with using your code and add a puts ErrorHandler.methods
after the handle_error_from
and you will see it has a create
method defined. The reason is that self is ErrorHandler
in this case.
You need to define the wrapper method after the original method is defined.
See here a full example.
module ErrorHandler
def handle_error_from(method_name)
define_singleton_method(method_name) do |*arguments|
begin
super(*arguments)
rescue
puts "Handler return"
end
end
end
end
class Foo
extend ErrorHandler
def self.create
raise "error"
end
handle_error_from "create"
end
Foo.create
Upvotes: 1