The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Reflex::Callbacks - Convenience functions for creating and using callbacks

VERSION

This document describes version 0.100, released on April 02, 2017.

SYNOPSIS

This package contains several helper functions, each with its own use case. Please see individual examples.

DESCRIPTION

Reflex::Callback and its subclasses implement the different types of calbacks that Reflex supports. Reflex::Callbacks provides convenience functions that are almost always used instead of Reflex::Callback objects.

Reflex::Callback's generic interface is a constructor and a single method, deliver(), which routes its parameters to their destination. Subclasses may implement additional methods to support specific use cases.

cb_method

Creates and returns Reflex::Callback::Method object. Accepts two positional parameters: the object reference and method name to invoke when the callback is delivered.

Relex::Callback::Method's SYNOPSIS has an example, as does the eg directory in Reflex's distribution.

cb_object

cb_object() converts the specification of multiple callbacks into a list of callback parameter names and their Reflex::Callback::Method objects. The returned list is in a form suitable for a Reflex::Base constructor.

cb_object() takes two positional parameters. The first is the object reference that will handle callbacks. The second describes the events and methods that will handle them. It may be a scalar string, an array reference, or a hash reference.

If the second parameter is a scalar string, then a single method will handle a single event. The event and method names will be identical. cb_object() will then return two values: the event name, and the Reflex::Callback::Method to invoke the corresponding object method.

        use Reflex::Callbacks qw(cb_object);
        my $object = bless {};
        my @cbs = cb_object($object, "event");

        # ... is equivalent to:

        use Reflex::Callback::Method;
        my $object = bless {};
        my @cbs = (
                on_event => Reflex::Callback::Method->new(
                        object => $object, method_name => "event"
                )
        );

If the second parameter is an array reference of event names, then one Reflex::Callback::Method will be created for each event. The event names and method names will be identical.

        use Reflex::Callbacks qw(cb_object);
        my $object = bless {};
        my @cbs = cb_object($object, ["event_one", "event_two"]);

        # ... is equivalent to:

        use Reflex::Callback::Method;
        my $object = bless {};
        my @cbs = (
                on_event_one => Reflex::Callback::Method->new(
                        object => $object, method_name => "event_one"
                ),
                on_event_two => Reflex::Callback::Method->new(
                        object => $object, method_name => "event_two"
                ),
        );

If the second parameter is a hash reference, then it should be keyed on event name. The corresponding values should be method names. This syntax allows event and method names to differ.

        use Reflex::Callbacks qw(cb_object);
        my $object = bless {};
        my @cbs = cb_object($object, { event_one => "method_one" });

        # ... is equivalent to:

        use Reflex::Callback::Method;
        my $object = bless {};
        my @cbs = (
                on_event_one => Reflex::Callback::Method->new(
                        object => $object, method_name => "method_one"
                )
        );

cb_class

cb_class() is an alias for cb_object(). Perl object and class methods currently behave the same, so there is no need for additional code at this time.

cb_role

cb_role() implements Reflex's role-based callbacks. These callbacks rely on method names to contain clues about the objects and events being handled. For instance, a method named on_resolver_answer() hints that it handles the "answer" events from a sub-object with the role of "resolver".

cb_role() requires two parameters and has a third optional one. The first two parameters are the callback object reference and the role of the object for which it handles events. The third optional parameter overrides the "on" prefix with a different one.

        {
                package Handler;
                sub on_resolver_answer { ... }
                sub on_resolver_failure { ... }
        }

        # This role-based definition:

        use Reflex::Callbacks qw(cb_role);
        my $object = Handler->new();
        my @cbs = cb_role($object, "resolver");

        # ... is equivalent to:

        use Reflex::Callbacks qw(cb_object);
        my $object = Handler->new();
        my @cbs = cb_object(
                $object, {
                        answer  => "on_resolver_answer",
                        failure => "on_resolver_failure",
                }
        );

        # ... or:

        use Reflex::Callbacks qw(cb_method);
        my $object = Handler->new();
        my @cbs = (
                on_answer => Reflex::Callback::Method->new(
                        object => $object, method_name => "on_resolver_answer"
                ),
                on_failure => Reflex::Callback::Method->new(
                        object => $object, method_name => "on_resolver_failure"
                ),
        );

cb_promise

cb_promise() takes a scalar reference. This reference will be populated with a Reflex::Callback::Promise object.

cb_promise() returns two values that are suitable to insert onto a Reflex::Base's constructor. The first value is a special event name, "on_promise", that tells Reflex::Base objects they may be used inline as promises. The second return value is the same Reflex::Callback::Promise object that was inserted into cb_promise()'s parameter.

        use Reflex::Callbacks qw(cb_promise);
        my $promise;
        my @cbs = cb_promise(\$promise);

        # ... is eqivalent to:

        use Reflex::Callback::Promise;
        my $promise = Reflex::Callback::Promise->new();
        @cbs = ( on_promise => $promise );

cb_coderef

cb_coderef() takes a single parameter, a coderef to callback. It returns a single value: a Reflex::Callback::Coderef object that will deliver events to the callback.

cb_coderef() neither takes nor returns an event name. As such, the Reflex::Base parameter name must be supplied outside cb_coderef().

        my $timer = Reflex::Interval->new(
                interval    => 1,
                auto_repeat => 1,
                on_tick     => cb_coderef { print "tick!\n" },
        );

As shown above, cb_coderef() is prototyped to make the callback's sub declaration optional.

Usages Outside Reflex

Reflex callbacks are designed to be independent of any form of concurrency. Reflex::Callbacks provides two convenience functions that other class libraries may find useful but Reflex doesn't use.

Please contact the authors if there's interest in using these functions, otherwise they may be deprecated.

gather_cb

The gather_cb() function extracts callbacks from an object's constructor parameters and encapsulates them in a Reflex::Callbacks object.

gather_cb() takes three parameters: The object that will own the callbacks, a hash reference containing a constructor's named parameters, and an optional regular expression to match callback parameter names. By default, gather_cb() will collect parameters matching /^on_/.

        package ThingWithCallbacks;
        use Moose;

        use Reflex::Callbacks qw(gather_cb);

        has cb => ( is => 'rw', isa => 'Reflex::Callbacks' );

        sub BUILD {
                my ($self, $arg) = @_;
                $self->cb(gather_cb($self, $arg));
        }

        sub run {
                my $self = shift;
                $self->cb()->deliver( event => {} );
        }

deliver

deliver() is a method of Reflex::Callback, not a function. It takes two parameters: the name of an event to deliver, and a hash reference containing named values to include with the event.

deliver() finds the callback that corresponds to its event. It then delivers the event to that callback. The callback must have been collected by gather_cb().

See the example for gather_cb(), which also invokes deliver().

SEE ALSO

Please see those modules/websites for more information related to this module.

BUGS AND LIMITATIONS

You can make new bug reports, and view existing ones, through the web interface at http://rt.cpan.org/Public/Dist/Display.html?Name=Reflex.

AUTHOR

Rocco Caputo <rcaputo@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2017 by Rocco Caputo.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

AVAILABILITY

The latest version of this module is available from the Comprehensive Perl Archive Network (CPAN). Visit http://www.perl.com/CPAN/ to find a CPAN site near you, or see https://metacpan.org/module/Reflex/.

DISCLAIMER OF WARRANTY

BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 568:

Nested L<> are illegal. Pretending inner one is X<...> so can continue looking for other errors.

Nested L<> are illegal. Pretending inner one is X<...> so can continue looking for other errors.