У меня есть существующая библиотека, состоящая из множества сервисов, которые все отвечают на метод execute
каждый метод выполняет свою логику c
class BaseService
def execute
raise NotImplementedError
end
end
class CreateUserService < BaseService
def execute
# Some code that does Other stuff
end
end
class NotifyService < BaseService
def execute
# Some code that does other other stuff
end
end
Я хотел бы сделать что-то для достижения sh что-то вроде:
class BaseService
around :execute do |&block|
puts 'Before'
block.call
puts 'After'
end
end
, который затем оборачивает каждый метод execute, включая дочерние классы, так что logi c может выполняться до и после.
Я сделал что-то вроде этого:
module Hooks
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def around(*symbols, &block)
to_prepend = build_module(symbols) do |*args, &mblock|
result = nil
block.call do
result = super(*args, &mblock)
end
result
end
prepend to_prepend
end
private
def build_module(symbols, &block)
Module.new do
symbols.each do |symbol|
define_method(symbol, &block)
end
end
end
end
end
class BaseService
include Hooks
around :execute do |&block|
puts 'before'
block.call
puts 'after'
end
# ..
end
Однако, когда метод around
выполняется только в базовом классе. Я предполагаю, что это связано с природой prepend
. Порядок предков выглядит так:
[<Module>, BaseService, Hooks, ...]
[NotifyService, <Module>, BaseService, Hooks, ...]
etc
Есть ли способ, которым я могу это сделать sh? Спасибо!