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 )