Beam-Emitter
view release on metacpan or search on metacpan
lib/Beam/Emitter.pm view on Meta::CPAN
#pod Coordinating Christmas Dinner with Beam::Emitter by Yanick Champoux.
#pod
#pod =back
#pod
#pod =cut
use strict;
use warnings;
use Types::Standard qw(:all);
use Scalar::Util qw( weaken refaddr );
use Carp qw( croak );
use Beam::Event;
use Module::Runtime qw( use_module );
use Moo::Role; # Put this last to ensure proper, automatic cleanup
# The event listeners on this object, a hashref of arrayrefs of
# EVENT_NAME => [ Beam::Listener object, ... ]
has _listeners => (
lib/Beam/Emitter.pm view on Meta::CPAN
sub subscribe {
my ( $self, $name, $sub, %args ) = @_;
my $class = delete $args{ class } || "Beam::Listener";
croak( "listener object must descend from Beam::Listener" )
unless use_module($class)->isa( 'Beam::Listener' );
my $listener = $class->new( %args, callback => $sub );
push @{ $self->_listeners->{$name} }, $listener;
weaken $self;
weaken $sub;
return sub {
$self->unsubscribe($name => $sub)
if defined $self;
};
}
#pod =method on ( event_name, subref )
#pod
#pod An alias for L</subscribe>. B<NOTE>: Do not use this alias for method
#pod modifiers! If you want to override behavior, override C<subscribe>.
lib/Beam/Emitter/Cookbook.pod view on Meta::CPAN
$emitter->on( 'event', sub { $object->method( @_ ) } );
But this has a couple drawbacks: It's a bunch of typing, and it closes
over a reference to your object which means your object lives as long as
the event emitter does. This can even cause circular references, which
are a common cause of memory problems in Perl.
To fix these problems, you could again do it manually:
use Scalar::Util qw( weaken );
weaken $object; # Reduce our object's reference count
$emitter->on( 'event', sub {
return unless $object; # We might have been cleaned up
$object->method( @_ );
} );
Or you could use the L<curry> module:
$emitter->on( 'event', $object->curry::weak::method );
The "curry" module creates new subroutine references from existing ones,
passing in any arguments. There's a corresponding "curry::weak" module
which does the same thing, but weakens any references used as arguments.
This is the easiest way to use object methods as event handlers.
=head2 Add custom data to an event handler
To add additional data to an event handler when it's created, you can
simply "close over" the variable in your new subroutine, like so:
my $name = "Doug";
$emitter->on( introduce => sub {
print "Hello, my name is $name";
( run in 0.324 second using v1.01-cache-2.11-cpan-65fba6d93b7 )