tl;dr version: Is it better for event handlers to have one method per type of
event? Or one method to accept all events? Or something else?
Currently event handlers (called EventWatchers) in Test::Builder2 implement
two methods: accept_event and accept_result. accept_result() is a special
case to handle results (which are special events) and accept_event() takes
care of everything else.
This means you wind up writing stuff like:
my %event_dispatch = (
"stream start" => "accept_stream_start",
"stream end" => "accept_stream_end",
"set plan" => "accept_set_plan",
"log" => "accept_log",
);
sub accept_event {
my $self = shift;
my($event, $ec) = @_;
my $type = $event->event_type;
my $method = $event_dispatch{$type};
return unless $method;
$self->$method($event, $ec);
return;
}
Which isn't too bad, but it seems like make-work.
The alternative is for the event handlers to have a method for each event,
(ie. accept_stream_start, etc...) falling back to accept_event if there is no
specific handler.
my $method = type2method($event->event_type);
$handler->can($method) ?
$handler->$method($event) : $handler->accept_event($method);
I chose a single method for all events for two reasons:
1) Speed. The event coordinator doesn't have to call can() on every handler
and every event.
2) It makes it easy to write a handler that slurps up all events, like the
History object.
It turns out #1 can be made moot with some careful programming. #2 can be
handled by falling back to a generic handler.
So now the question is one of good event handler design, which I don't have
experience with. How does one design a good event handler? Is the pattern
one method per type of event? Or one method to do the dispatching? Or
something else?
--
Being faith-based doesn't trump reality.
-- Bruce Sterling