Manpage logo

Mixin::Event::Dispatch - mixin methods for simple event/message dispatch framework

NAME  VERSION  SYNOPSIS  DESCRIPTION  SPECIAL EVENTS  METHODS  invoke_event  subscribe_to_event  unsubscribe_from_event  add_handler_for_event  event_handlers  clear_event_handlers  API HISTORY  ROLE vs. MIXIN  SEE ALSO  AUTHOR  LICENSE 

NAME

Mixin::Event::Dispatch − mixin methods for simple event/message dispatch framework

VERSION

version 2.000

SYNOPSIS

# Add a handler then invoke it
package Some::Class;
use parent qw(Mixin::Event::Dispatch);
sub new { bless {}, shift }
my $obj = Some::Class−>new;
# Subscribe to events − subscribers will be called with an event object,
# and any event parameters, each time the event is raised.
$obj−>subscribe_to_event(another_event => (my $code = sub {
my $ev = shift;
warn "[] @_";
}));
$obj−>invoke_event(another_event => 'like this');
# should get output 'Event data: like this'
$obj−>unsubscribe_from_event(another_event => $code);
# Note that handlers will be called for each instance of an event until they return false,
# at which point the handler will be removed, so for a permanent handler, make sure to return 1.
$obj−>add_handler_for_event(some_event => sub { my $self = shift; warn "had some_event: @_"; 1; });
$obj−>invoke_event(some_event => 'message here');
# Attach event handler for all on_XXX named parameters
package Event::User;
sub configure {
my $self = shift;
my %args = @_;
$self−>add_handler_for_event(
map { (/ˆon_(.*)$/) ? ($1 => $args{$_}) : () } keys %args
);
return $self;
}

DESCRIPTION

Add this in as a parent to your class, and it'll provide some methods for defining event handlers ("subscribe_to_event" or "add_handler_for_event") and calling them ("invoke_event").

Note that handlers should return 0 for a one−off handler, and 1 if it should be called again on the next event.

SPECIAL EVENTS

A single event has been reserved for cases where a callback dies:

" event_error " − if a handler is available, this will be called instead of dying whenever any other handler dies. If an " event_error " handler also fails, then this error will be re−thrown. As with the other handlers, you can have more than one " event_error " handler.

METHODS

invoke_event

Takes an "event" parameter, and optional additional parameters that are passed to any callbacks.

$self−>invoke_event('new_message', from => 'fred', subject => 'test message');

Returns $self if a handler was found, undef if not.

subscribe_to_event

Subscribe the given coderef to the named event.

Called with a list of event name and handler pairs. An event name can be any string value. The handler is one of the following:

a coderef will be used directly as a handler, and will be passed the Mixin::Event::Dispatch::Event object representing this event.

a plain string will be used as a method name

a subclass of Mixin::Event::Dispatch will be used to delegate the event − use this if you have an object hierarchy and want the parent object to handle events on the current object

If you have an overloaded object which is both a Mixin::Event::Dispatch subclass and provides a coderef overload, it will default to event delegation behaviour. To ensure the overloaded coderef is used instead, pass \&$obj instead.

All handlers will be given an event (a Mixin::Event::Dispatch::Event object) as the first parameter, and any passed event parameters as the remainder of @_.

Example usage:

my $parent = $obj−>parent;
$obj−>subscribe_to_event(
connect => sub { warn shift−>name }, # warns 'connect'
connect => $parent, # $parent−>invoke_event(connect => @_)
connect => \&$parent, # $parent's overloaded &{}
joined => 'on_joined', # the on_joined method in $obj
);

Note that multiple handlers can be assigned to the same event name.

unsubscribe_from_event

Removes the given coderef from the list of handlers for this event.

Expects pairs of (event name, coderef) entries for the events to unsubscribe from.

Example usage:

$obj−>subscribe_to_event(
some_event => (my $code = sub { }),
);
$obj−>unsubscribe_from_event(
some_event => $code,
);

If you need to unsubscribe from the event currently being handled, try the "unsubscribe" in Mixin::Event::Dispatch::Event method.

Returns $self.

add_handler_for_event

Adds handlers to the stack for the given events.

$self−>add_handler_for_event(
new_message => sub { warn @_; 1 },
login => sub { warn @_; 1 },
logout => sub { warn @_; 1 },
);

event_handlers

Accessor for the event stack itself − should return a hashref which maps event names to arrayrefs for the currently defined handlers.

clear_event_handlers

Removes all queued event handlers.

Will also be called when defining the first handler to create the initial "event_handlers" entry, should be overridden by subclass if something other than $self−>{event_handlers} should be used.

API HISTORY

Version 2.000 (will) implement the Mixin::Event::Dispatch::Methods class.

Version 1.000 implemented "subscribe_to_event" and Mixin::Event::Dispatch::Event.

Version 0.002 changed to use "event_handlers" instead of " event_stack " for storing the available handlers (normally only invoke_event and add_handler_for_event are expected to be called directly).

ROLE vs. MIXIN

Role systems might work using the Mixin::Event::Dispatch::Methods module, which allows import of the relevant methods. Try combing this with a thin wrapper using Role::Tiny / Moo::Role / Moose for that. The "t/moo−role.t" and "t/role−tiny.t" tests may provide some inspiration.

Alternatively, you could perhaps use this as a component via Class::C3::Componentised.

(I haven't really used any of the above options myself, please let me know if I'm spreading disinformation here)

SEE ALSO

There are at least a dozen similar modules already on CPAN, here's a small sample:

Event::Distributor − uses Future to sequence callbacks, implementing the concepts discussed in Event−Reflexive programming <http://leonerds-code.blogspot.co.uk/search/label/event-reflexive>

Object::Event − event callback interface used in several AnyEvent modules.

Ambrosia::Event − part of the Ambrosia web application framework

Net::MessageBus − event subscription via TCP−based message bus

Event::Wrappable − wrapping for event listeners

MooseX::Event − node.js−inspired events, for Moose users

Beam::Emitter − a Moo::Role for event handling

Note that some frameworks such as Reflex, POE and Mojolicious already have comprehensive message−passing and callback interfaces.

If you're looking for usage examples, try the following:

Adapter::Async

Net::Async::AMQP

EntityModel − uses this as the underlying event−passing mechanism, with some support in EntityModel::Class for indicating event usage metadata

Protocol::PostgreSQL − mostly an adapter converting PostgreSQL database messages to/from events using this class

Protocol::IMAP − the same, but for the IMAPv4bis protocol

Protocol::XMPP − and again for Jabber/XMPP

AUTHOR

Tom Molesworth <[email protected]>

with thanks to various helpful people on freenode #perl who suggested making "event_handlers" into an accessor (to support non−hashref objects) and who patiently tried to explain about roles.

Mixin::Event::Dispatch::Methods suggested by mst, primarily for better integration with object systems such as Moo(se).

LICENSE

Copyright Tom Molesworth 2011−2015, based on code originally part of EntityModel. Licensed under the same terms as Perl itself.


Updated 2026-06-01 - jenkler.se | uex.se