Я написал модуль для подключения методов до или после вызова метода экземпляра.Я хотел бы применить эти хуки ко всем классам, которые наследуются от родительского класса.Однако, если я напишу хук в родительском классе, он не будет выполнен, он будет выполнен, только если он присутствует в дочернем классе.
Это модуль для создания хуков:
module Hooks
def self.included(base)
base.send :extend, ClassMethods
end
module ClassMethods
# everytime we add a method to the class we check if we must redifine it
def method_added(method)
if @hooker_before && (@methods_to_hook_before.include?(method)|| @methods_to_hook_after.include?(method)) && !@methods_seen.include?(method)
hooked_method_before = instance_method(@hooker_before) if @hooker_before
hooked_method_after = instance_method(@hooker_after) if @hooker_after
@methods_to_hook_before.each do |method_name|
begin
method_to_hook = instance_method(method_name)
rescue NameError => e
return
end
@methods_seen.push(method)
define_method(method_name) do |*args, &block|
hooked_method_before.bind(self).call if hooked_method_before
method_to_hook.bind(self).(*args, &block) ## your old code in the method of the class
hooked_method_after.bind(self).call if hooked_method_after
end
end
end
end
def before(*methods_to_hook, hookers)
@methods_to_hook_before = methods_to_hook
@methods_to_hook_after = [] unless @methods_to_hook_after
@hooker_before = hookers[:call]
@methods_seen = []
end
def after(*methods_to_hook, hookers)
@methods_to_hook_after = methods_to_hook
@methods_to_hook_before = [] unless @methods_to_hook_before
@hooker_after = hookers[:call]
@methods_seen = []
end
end
end
module Utilities
def before_generate
puts("in before generate utilities")
end
end
class Parent
include Utilities
include Hooks
def generate
puts("in generate Parent")
end
end
class Child < Parent
before :generate, call: :before_generate
def generate
puts("in child generate")
end
end
class AnotherChild < Parent
before :generate, call: :before_generate
def generate
puts("in child generate")
end
end
Child.new.generate()
выдает желаемый результат: перед генерацией утилит в дочерней генерации. Однако я бы хотел, чтобы все классы, которые наследуются от Parent, автоматически наследовали от этого поведения.Добавление before :generate, call: :before_generate
в родительский класс не поможет.Есть ли способ обернуть все дочерние классы в одном модуле?Есть ли способ достичь этого или я должен воспроизвести вызов before в каждом отдельном дочернем классе, где я этого хочу.