#使分配程序能够使用注册回调的返回值
A simple change to the EventDispatcher class makes it possible for the dispatcher to use the return values of the registered callbacks. The original implementation of EventDispatcher#notify called the registered code blocks, but ignored their return value. This version of EvenTDispatcher#notify yields the return values to a block passed in to notify:
Here's an insultingly simple portal rendering engine. It lets boxes register to be rendered inside an HTML table, on one of two rows on the portal page:
A simple change to the EventDispatcher class makes it possible for the dispatcher to use the return values of the registered callbacks. The original implementation of EventDispatcher#notify called the registered code blocks, but ignored their return value. This version of EvenTDispatcher#notify yields the return values to a block passed in to notify:
module EventDispatcher
def notify(event, *args)
if @event_dispatcher_listeners[event]
@event_dispatcher_listeners[event].each do |m|
yield(m.call(*args)) if m.respond_to? :call
end
end
return nil
end
end
Here's an insultingly simple portal rendering engine. It lets boxes register to be rendered inside an HTML table, on one of two rows on the portal page:
class Portal
include EventDispatcher
def initialize
setup_listeners
end
def render
puts '<table>'
render_block = Proc.new { |box| puts " <td>#{box}</td>" }
[:row1, :row2].each do |row|
puts ' <tr>'
notify(row, &render_block)
puts ' </tr>'
end
puts '</table>'
end
end
portal = Portal.new
portal.subscribe(:row1) { 'Stock Ticker' }
portal.subscribe(:row1) { 'Weather' }
portal.subscribe(:row2) { 'Pointless, Trivial News' }
portal.render # <table>
# <table>
# <tr>
# <td>Stock Ticker</td>
# <td>Weather</td>
# </tr>
# <tr>
# <td>Pointless, Trivial News</td>
# </tr>
# </table>