Delegate block in broadcast logger method_missing

When a method called on a broadcast logger is passed a block, it should
be forwarded to all subscribed loggers.
This commit is contained in:
Eugene Kenny 2023-10-02 16:35:01 +01:00
parent 832fb1de70
commit 5574a2fcb4
2 changed files with 22 additions and 4 deletions

View File

@ -203,16 +203,20 @@ module ActiveSupport
@broadcasts.each { |logger| block.call(logger) }
end
def method_missing(name, *args)
def method_missing(name, *args, &block)
loggers = @broadcasts.select { |logger| logger.respond_to?(name) }
if loggers.none?
super(name, *args)
super(name, *args, &block)
elsif loggers.one?
loggers.first.send(name, *args)
loggers.first.send(name, *args, &block)
else
loggers.map { |logger| logger.send(name, *args) }
loggers.map { |logger| logger.send(name, *args, &block) }
end
end
def respond_to_missing?(method, include_all)
@broadcasts.any? { |logger| logger.respond_to?(method, include_all) }
end
end
end

View File

@ -268,6 +268,16 @@ module ActiveSupport
assert(logger.foo)
end
test "calling a method that accepts a block" do
logger = BroadcastLogger.new(CustomLogger.new)
called = false
logger.bar do
called = true
end
assert(called)
end
class CustomLogger
attr_reader :adds, :closed, :chevrons
attr_accessor :level, :progname, :formatter, :local_level
@ -286,6 +296,10 @@ module ActiveSupport
true
end
def bar
yield
end
def debug(message, &block)
add(::Logger::DEBUG, message, &block)
end