class EventHandler(EventClass) macro make_callback(event_class) alias Callback = Callback, {{ event_class }} -> Nil end make_callback(EventClass) def initialize @s = Hash(EventClass, Array(Callback)).new end def add( event, &block : Callback, EventClass -> Nil ) : Callback, EventClass -> Nil @s[event.class] ||= Array(Callback).new @s[event.class] << block block end end class Event; end class EventA < Event; end class EventB < Event; end h = EventHandler.new(Event) a1 = h.add(EventA.new) { |cb, event| puts :EventA } a2 = h.add(EventA.new) { |cb, event| puts :EventA2 } b1 = h.add(EventB.new) { |cb, event| puts :EventB } h.remove(a1)