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

NAME

Reflex::Role::Object - Make an object reactive (aka, event driven).

VERSION

version 0.011

SYNOPSIS

With Moose:

        package Object;
        use Moose;
        with 'Reflex::Role::Object';

        ...;

        1;

Without Moose:

        # Sorry, roles are defined and composed using Moose.
        # However, Reflex::Object may be used the old fashioned way.

DESCRIPTION

Reflex::Role::Object provides Reflex's event-driven features to other objects. It provides public methods that help use reactive objects and to write them.

Public Attributes

session_id

Each Reflex object is associated with a POE session, although a single session may (and usually does) drive several objects. Reflex objects expose session_id() for times where it's important to know which session owns them. Usually when interfacing between Reflex and POE.

session_id() is rarely needed, especially since Reflex provides helper classes for working with POE modules. Please see one or more of: Reflex::POE::Event, Reflex::POE::Postback, Reflex::POE::Session, Reflex::POE::Wheel and Reflex::POE::Wheel::Run.

        sub method {
                my $self = shift;
                print(
                        "I, $self, am driven by POE::Sesson ID ",
                        $self->session_id(), "\n"
                );
        }

observe

observe() allows one object (the observer) to register interest in events emitted by another. It takes three named parameters: "observed" must contain a Reflex object (either a Reflex::Role::Object consumer, or a Reflex::Object subclass). "event" contains the name of an event that the observed object emits. Finally, "callback" contains a Reflex::Callback that will be invoked when the event occurs.

        use Reflex::Callbacks(cb_method);

        $self->observe(
                observed  => $an_object_maybe_myself,
                event     => "occurrence",
                callback  => cb_method($self, "method_name"),
        );

emit

Emit an event. This triggers callbacks for anything waiting for the event from the object that emitted it. Callback invocation is often synchronous, but this isn't guaranteed. Later versions of Reflex will support remote objects, where the emitter and callback may not be in the same room.

Emit takes two named parameters so far: "event" names the event being emitted and is required. "args" allows data to be passed along with the event, and it should contain a hashref of named values.

Reflex::Stream emits a "failure" event when things don't go as planned:

        sub _emit_failure {
                my ($self, $errfun) = @_;

                $self->emit(
                        event => "failure",
                        args  => {
                                data    => undef,
                                errnum  => ($!+0),
                                errstr  => "$!",
                                errfun  => $errfun,
                        },
                );

                return;
        }

ignore

The ignore() method tells Reflex that one object has lost interest in events from another. It takes two named parameters. "observed" is required and indicates which object is being ignored. "events" is an optional array reference containing zero or more event names to ignore.

        $self->ignore(
                observed => $an_object_maybe_myself,
                events   => [qw( success failure )],
        );

All events will be ignored if "events" is not specified:

        $self->ignore(
                observed => $an_object_maybe_myself,
        );

An object may destruct while it's being watched and/or is watching other objects. DEMOLISH will ensure that all watchers related to the outgoing object are cleaned up. Therefore it's usually more convenient to just destroy things when done with them.

call_gate

call_gate() is a helper that ensures a method is called from the same POE::Session instance that owns its object. It's mainly of interest to authors of POE modules and their Reflex interfaces. Other users may never need it.

POE consumers often return responses to the sessions that made requests. For Reflex objects to receive these responses, they must first send their requests from the right sessions. call_gate() helps by ensuring this.

call_gate() takes one required positional parameter: the name of the method calling call_gate(). Any other parameters are passed back to the method, re-creating @_ as it was originally.

call_gate() immediately returns 1 if it's called from the correct session. Otherwise it re-invokes the method in the proper session and returns 0.

It's important to put call_gate() first in methods that need it, and for them to return immediately fi call_gate() returns false.

This method from Reflex::Signal makes sure the signal is watched by the same session that owns the object doing the watching:

        sub start_watching {
                my $self = shift;
                return unless $self->call_gate("start_watching");
                $POE::Kernel::poe_kernel->sig($self->name(), "signal_happened");
        }

run_within_session

run_within_session() is another helper method to ensure some code is running in the POE session that POE modules may expect. It takes one required positional parameter, a code reference to invoke or the name of a method to call on $self. Any other parameters are passed to the code that will be executed.

For example the IRC bot in eg/eg-13-irc-bot.pl wants to register callbacks with POE::Component::IRC. It calls a couple $bot->yield() methods within the object's session. This helps the component know where to send its responses:

        sub BUILD {
                my $self = shift;

                # Set up $self->component() to contain
                # a POE::Component::IRC object.

                ...;

                # Register this object's interest in the component,
                # via the session that owns this object.
                $self->run_within_session(
                        sub {
                                $self->component()->yield(register => "all");
                                $self->component()->yield(connect  => {});
                        }
                )
        }

wait

Wait for an object to emit() a promised event. Requires the object to emit an event that isn't already explicitly handled. All Reflex objects will run in the background while wait() blocks.

wait() returns the next event emitted by an object. Objects cease to run while your code processes the event, so be quick about it.

Here's most of eg/eg-32-promise-tiny.pl, which shows how to wait() on events from a Reflex::Timer.

        use Reflex::Timer;

        my $t = Reflex::Timer->new(
                interval    => 1,
                auto_repeat => 1,
        );

        while (my $event = $t->wait()) {
                print "wait() returned event '$event->{name}'...\n";
        }

It's tempting to rename this method next().

run_all

Run all active Reflex objects until they destruct. This will not return discrete events, like wait() does. It will not return at all before the program is done. It returns no meaningful value yet.

run_all() is useful when you don't care to wait() on objects individually. You just want the program to run 'til it's done.

EXAMPLES

Many of the examples in the distribution's eg directory use Reflex objects. Explore and enjoy!

SEE ALSO

Moose::Manual::Concepts

Reflex Reflex::Object

"ACKNOWLEDGEMENTS" in Reflex "ASSISTANCE" in Reflex "AUTHORS" in Reflex "BUGS" in Reflex "BUGS" in Reflex "CONTRIBUTORS" in Reflex "COPYRIGHT" in Reflex "LICENSE" in Reflex "TODO" in Reflex