我今天从@avdi 的 Ruby Tapas 节目中获得了以下代码:
module Eventful
def self.included(other)
other.extend(Macros)
end
def add_listener(listener)
(@listeners ||= []) << listener
end
def notify_listeners(event, *args)
(@listeners || []).each do |listener|
listener.public_send("on_#{event}", *args)
end
end
module Macros
def event(name)
module_eval(%Q{
def #{name}(*args)
notify_listeners(:#{name}, *args)
end
})
end
end
end
class Dradis
include Eventful
event :new_contact
end
class ConsoleListener
def on_new_contact(direction, range)
puts "DRADIS contact! #{range} kilometers, bearing #{direction}"
end
end
dradis = Dradis.new
dradis.add_listener(ConsoleListener.new)
dradis.new_contact(120, 23000)
我了解事件和侦听器以及观察者模式的概念,但不明白这种语法是如何/为什么起作用的,也没有在任何手册中看到它。类Dradis
有这个:
event :new_contact
起初,我认为这event
是一个方法,:new_contact
是一个参数,所以我会调用event
的一个实例Dradis
,例如:
dradis = Dradis.new
dradis.event
而是在类似new_contact
的实例上调用Dradis
:
dradis = Dradis.new
dradis.add_listener(ConsoleListener.new)
dradis.new_contact(120, 23000)
并触发event
宏模块中的方法。
谁能解释为什么它会这样工作?调用:new_contact
实例dradis
来触发事件方法?