Mixin::...ispatch(3)

๐Ÿ“ฆ version 2.000, in alpine 3.24

๐ŸŒธ NAME ๐ŸŒธ

Mixin::Event::Dispatch(3) โ€” straight from the User Contributed Perl Documentation โ€” is your bestie for mixin methods for simple event/message dispatch framework. ๐Ÿ’–

๐ŸŽ€ VERSION ๐ŸŽ€

version 2.000 โ€” periodt. โœจ

โœจ SYNOPSIS โœจ

okay so here's the absolute blueprint, bestie โ€” code block stays exactly as-is, I'm not touching a single character:

# 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 <cpan@perlsite.co.uk> ๐Ÿ˜

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. ๐Ÿ’–


๐Ÿ’– That's the whole page, bestie! Source/version: perl v5.42.2; date: 2026-02-15; and yes, this is the Mixin::...ispatch(3) manual page. Go dispatch like the main character you are! ๐Ÿซถโœจ

๐Ÿ“ฆ where this page comes from