From 3f1c48a08aaf3505d618fe3317844f9cb0d8a4de Mon Sep 17 00:00:00 2001 From: Rocco Caputo Date: Tue, 20 Apr 2010 02:56:34 -0400 Subject: [PATCH] Write more documentation. --- dist.ini | 10 ++-- eg/EchoStream.pm | 4 +- lib/Reflex/Callback/CodeRef.pm | 4 +- lib/Reflex/Callback/Method.pm | 4 +- lib/Reflex/Callback/Promise.pm | 4 +- lib/Reflex/Collection.pm | 88 +++++++++++++++++++++++++++++++++- lib/Reflex/Timer.pm | 83 ++++++++++++++++---------------- lib/Reflex/Trait/Emitter.pm | 87 ++++++++++++++------------------- lib/Reflex/Trait/Observer.pm | 58 +++++++++++----------- 9 files changed, 203 insertions(+), 139 deletions(-) diff --git a/dist.ini b/dist.ini index 5c28612..f434fc2 100644 --- a/dist.ini +++ b/dist.ini @@ -4,16 +4,15 @@ author = Rocco Caputo license = Perl_5 copyright_holder = Rocco Caputo -[MetaResources] -bugtracker = http://rt.cpan.org/Public/Dist/Display.html?Name=Reflex -repository = http://github.com/rcaputo/reflex - [Prereq] Scalar::Util = 1.21 POE = 1.268 Test::More = 0.94 Moose = 0.92 +[Repository] +git_remote = gh + [ReadmeFromPod] [ReadmeMarkdownFromPod] [AllFiles] @@ -30,6 +29,9 @@ Moose = 0.92 [MakeMaker] [ChangelogFromGit] +; Not ready, unfortunately. +;[CreditsFromGit] + ; Goes last to pick up generated files. [Manifest] diff --git a/eg/EchoStream.pm b/eg/EchoStream.pm index e5ff5b2..92f7a68 100644 --- a/eg/EchoStream.pm +++ b/eg/EchoStream.pm @@ -10,12 +10,12 @@ sub on_stream_data { sub on_stream_failure { my ($self, $args) = @_; warn "$args->{errfun} error $args->{errnum}: $args->{errstr}\n"; - $self->emit( event => "shutdown", args => {} ); + $self->emit( event => "stopped", args => {} ); } sub on_stream_closed { my ($self, $args) = @_; - $self->emit( event => "shutdown", args => {} ); + $self->emit( event => "stopped", args => {} ); } sub DEMOLISH { diff --git a/lib/Reflex/Callback/CodeRef.pm b/lib/Reflex/Callback/CodeRef.pm index 7680e3b..c35a5d5 100644 --- a/lib/Reflex/Callback/CodeRef.pm +++ b/lib/Reflex/Callback/CodeRef.pm @@ -24,7 +24,7 @@ Reflex::Callback::CodeRef - Callback adapter for plain code references =head1 SYNOPSIS -In practice: +Used within Reflex: use Reflex::Callbacks qw(cb_coderef); @@ -38,7 +38,7 @@ In practice: $ct->run_all(); -Specifically: +Low-level usage: sub callback { my $arg = shift; diff --git a/lib/Reflex/Callback/Method.pm b/lib/Reflex/Callback/Method.pm index 23faf1f..6805c88 100644 --- a/lib/Reflex/Callback/Method.pm +++ b/lib/Reflex/Callback/Method.pm @@ -25,7 +25,7 @@ Reflex::Callback::Method - Callback adapter for class and object methods =head1 SYNOPSIS -In practice: +Used within Reflex: package MethodHandler; use Moose; @@ -55,7 +55,7 @@ In practice: MethodHandler->new()->run_all(); -Specifically: +Low-level usage: { package Object; diff --git a/lib/Reflex/Callback/Promise.pm b/lib/Reflex/Callback/Promise.pm index 7734f32..6c032f6 100644 --- a/lib/Reflex/Callback/Promise.pm +++ b/lib/Reflex/Callback/Promise.pm @@ -36,7 +36,7 @@ Reflex::Callback::Promise - Condvar-like non-callback adapter =head1 SYNOPSIS -In practice: +Used within Reflex: use Reflex::Timer; use ExampleHelpers qw(eg_say); @@ -50,7 +50,7 @@ In practice: eg_say("promise timer returned an event (@$event)"); } -Specifically: +Low-level usage: use Reflex::Callback::Promise; diff --git a/lib/Reflex/Collection.pm b/lib/Reflex/Collection.pm index eb08956..990e06b 100644 --- a/lib/Reflex/Collection.pm +++ b/lib/Reflex/Collection.pm @@ -15,7 +15,7 @@ has objects => ( sub remember { my ($self, $object) = @_; - $self->observe($object, shutdown => cb_method($self, "cb_forget")); + $self->observe($object, stopped => cb_method($self, "cb_forget")); $self->objects()->{$object} = $object; } @@ -30,4 +30,88 @@ sub cb_forget { } 1; -# TODO - Document. + +__END__ + +=head1 NAME + +Reflex::Collection - Autmatically manage a collection of Reflex objects + +=head1 SYNOPSIS + + package TcpEchoServer; + + use Moose; + extends 'Reflex::Listener'; + use Reflex::Collection; + use EchoStream; + + has clients => ( + is => 'rw', + isa => 'Reflex::Collection', + default => sub { Reflex::Collection->new() }, + handles => { remember_client => "remember" }, + ); + + sub on_listener_accepted { + my ($self, $args) = @_; + $self->remember_client( + EchoStream->new( + handle => $args->{socket}, + rd => 1, + ) + ); + } + + 1; + +=head1 DESCRIPTION + +Some object manage collections of other objects. For example, network +servers must track objects that represent client connections. If not, +those objects would go out of scope, destruct, and disconnect their +clients. + +Reflex::Collection is a generic object collection manager. It exposes +remember() and forget(), which may be mapped to other methods using +Moose's "handles" aspect. + +Reflex::Collection goes beyond this simple hash-like interface. It +will automatically forget() objects that emit "stopped" events, +triggering their destruction if nothing else refers to them. This +eliminates a large amount of repetitive work. + +=head2 new + +Create a new Reflex::Collection. It takes no parameters. + +=head2 remember + +Remember an object. Reflex::Collection works best if it contains the +only references to the objects it manages, so you may often see +objects remembered while they're constructed. See the SYNOPSIS for +one such example. + +remember() takes one parameter: the object to remember. + +=head2 forget + +Forget an object, returning its reference. You've supplied the +reference, so the returned one is usually redundant. forget() takes +one parameter: the object to forget. + +=head1 SEE ALSO + +L + +L +L +L +L +L +L +L +L +L + +=cut diff --git a/lib/Reflex/Timer.pm b/lib/Reflex/Timer.pm index f7a782a..bb51aa2 100644 --- a/lib/Reflex/Timer.pm +++ b/lib/Reflex/Timer.pm @@ -72,73 +72,72 @@ sub stop { } 1; -# TODO - Document. __END__ =head1 NAME -Reflex::Timer - Observe the passage of time. +Reflex::Timer - An object that observes the passage of time. =head1 SYNOPSIS -# Not a complete program. Many of the examples use Reflex::Timer. -# You can't throw a stone without hitting one. + # Several examples in the eg directory use Reflex::Timer. - sub object_method { - my ($self, $args) = @_; + use warnings; + use strict; - $self->timer( - Reflex::Timer->new( - interval => 1, - auto_repeat => 1, - ) - ); - ); + use lib qw(../lib); -=head1 DESCRIPTION + use Reflex::Timer; -Reflex::Timer emits events to mark the passage of time. + my $t = Reflex::Timer->new( + interval => 1, + auto_repeat => 1, + ); -Its constructor takes a hash as an argument. -The interval specifies the interval between events are fired. -auto_repeat is either specified as 1 or not specified and in the former -case, the events will be fired repeatedly and in the latter, only one event -is fired. -event_name is a key in the hash that specifies what the event emitted should -be called. -TODO - Complete the API. It's currently very incomplete. It only -handles relative delays via its "interval" constructor parameter, and -automatic repeat via "auto_repeat". + while (my $event = $t->wait()) { + print "wait() returned an event (@$event)\n"; + } -TODO - Complete the documentation. +=head1 DESCRIPTION -=head1 GETTING HELP +Reflex::Timer emits events to mark the passage of time. Its interface +is new and small. Please contact the Reflex project if you need other +features, or send us a pull request at github or gitorious. -L +=head1 PUBLIC ATTRIBUTES -=head1 ACKNOWLEDGEMENTS +=head2 interval -L +Define the interval between creation and the "tick" event's firing. +If auto_repeat is also set, this becomes the interval between +recurring "tick" events. -=head1 SEE ALSO +=head2 auto_repeat -L and L +A Boolean value. When true, Reflex::Timer will repeatedly fire "tick" +events every interval seconds. -=head1 BUGS +=head1 PUBLIC EVENTS -L +=head2 tick -=head1 CORE AUTHORS +Reflex::Timer emits "tick" events. We're looking for a better name, +so this may change in the future. Your suggestions can help solidify +the interface quicker. -L - -=head1 OTHER CONTRIBUTORS - -L +=head1 SEE ALSO -=head1 COPYRIGHT AND LICENSE +L -L +L +L +L +L +L +L +L +L +L =cut diff --git a/lib/Reflex/Trait/Emitter.pm b/lib/Reflex/Trait/Emitter.pm index 55c0dc6..28d5279 100644 --- a/lib/Reflex/Trait/Emitter.pm +++ b/lib/Reflex/Trait/Emitter.pm @@ -73,81 +73,64 @@ has event => ( }, ); -has setup => ( - isa => 'CodeRef|HashRef', - is => 'ro', -); - package Moose::Meta::Attribute::Custom::Trait::Reflex::Trait::Emitter; sub register_implementation { 'Reflex::Trait::Emitter' } 1; -# TODO - Document. __END__ =head1 NAME -Reflex::Trait::Emitter - Automatically emit events when values change. +Reflex::Trait::Emitter - Emit an event when an attribute's value changes. =head1 SYNOPSIS - # Not a complete program. See examples eg-09-emitter-trait.pl and - # eg-10-setup.pl for working examples. - - { - package Counter; - use Moose; - extends 'Reflex::Object'; - use Reflex::Trait::Emitter; - - has count => ( - traits => ['Reflex::Trait::Emitter'], - isa => 'Int', - is => 'rw', - default => 0, - ); - } + # Not a complete program. See examples eg-09-emitter-trait.pl + # and eg-10-setup.pl for working examples. -=head1 DESCRIPTION + package Counter; + use Moose; + extends 'Reflex::Object'; + use Reflex::Trait::Emitter; -Reflex::Trait::Emitter causes events to be emitted whenever an object -member's value changes. In the SYNOPSIS example, changes to the value -of count() cause the Counter object to emit "count" events. Each -event is accompanied by the new value. + has count => ( + traits => ['Reflex::Trait::Emitter'], + isa => 'Int', + is => 'rw', + default => 0, + ); -Custom mutators and methods may also use Reflex::Object's emit() -method to announce their own changes. Reflex::Trait::Emitter is -expected to handle many common scenarios. - -TODO - Complete the documentation. +=head1 DESCRIPTION -=head1 GETTING HELP +An attribute with the Reflex::Trait::Emitter trait emit an event on +behalf of its object whenever its value changes. The event will be +named after the attribute by default. It will be accompanied by a +"value" parameter, the value of which is the attribute's new value at +the time of the change. -L +In the SYNOPSIS example, changes to count() cause its Counter object +to emit "count" events. -=head1 ACKNOWLEDGEMENTS +=head2 event -L +The "default" option can be used to override the default event emitted +by the Reflex::Trait::Emitter trait. That default, by the way, is the +name of the attribute. =head1 SEE ALSO -L and L - -=head1 BUGS +L +L +L +L +L L - -=head1 CORE AUTHORS - -L - -=head1 OTHER CONTRIBUTORS - -L - -=head1 COPYRIGHT AND LICENSE - -L +L +L +L +L +L =cut diff --git a/lib/Reflex/Trait/Observer.pm b/lib/Reflex/Trait/Observer.pm index 7cd2101..8f832ce 100644 --- a/lib/Reflex/Trait/Observer.pm +++ b/lib/Reflex/Trait/Observer.pm @@ -97,7 +97,6 @@ package Moose::Meta::Attribute::Custom::Trait::Reflex::Trait::Observer; sub register_implementation { 'Reflex::Trait::Observer' } 1; -# TODO - Document. __END__ @@ -119,50 +118,47 @@ Reflex::Trait::Observer - Automatically observe Reflex objects. =head1 DESCRIPTION -Reflex::Trait::Observer allows an object to automatically observe -other objects it owns. In the SYNOPSIS, storing a Reflex::Timer in -clock() allows the owner to observe the timer's events. +Reflex::Trait::Observer allows one Reflex::Object to automatically +observe other another it has stored in an attribute. In the SYNOPSIS, +storing a Reflex::Timer in the clock() attribute allows the owner to +observe the timer's events. -Reflex::Object has explicit methods to do this, namely observe() and -observe_role(), but they are more verbose. +This trait is a bit of Moose-based syntactic sugar for +Reflex::Object's more explict observe() and observe_role() methods. -The "setup" attribute option provides default constructor parameters -for the attribute. In the above example, clock() will by default -contain +=head2 setup + +The "setup" option provides default constructor parameters for the +attribute. In the above example, clock() will by default contain Reflex::Timer->new(interval => 1, auto_repeat => 1); In other words, it will emit the Reflex::Timer event ("tick") once per second until destroyed. -TODO - Complete the documentation. - -=head1 GETTING HELP +=head2 role -L +Attribute events are mapped to the owner's methods using Reflex's +role-based callback convention. For example, Reflex will look for an +on_clock_tick() method to handle "tick" events from an object with the +'clock" role. -=head1 ACKNOWLEDGEMENTS - -L +The "role" option allows roles to be set or overridden. An observer +attribute's name is its default role. =head1 SEE ALSO -L and L - -=head1 BUGS +L +L +L +L +L L - -=head1 CORE AUTHORS - -L - -=head1 OTHER CONTRIBUTORS - -L - -=head1 COPYRIGHT AND LICENSE - -L +L +L +L +L +L =cut