Skip to content

Commit

Permalink
Add simpler has_many syntax for Reflex::Collection.
Browse files Browse the repository at this point in the history
  • Loading branch information
rcaputo committed Sep 6, 2010
1 parent aeb3852 commit 134c7e0
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 51 deletions.
25 changes: 0 additions & 25 deletions TODO
Expand Up @@ -14,29 +14,4 @@ I've done a half-baked implementation, but it needs:

---

Declarative syntactic sugar for collection attributes.
Try to get it into the 0.080 release.

They currently look like this:

has connections => (
is => 'rw',
isa => 'Reflex::Collection',
default => sub { Reflex::Collection->new() },
handles => { remember_client => "remember" },
);

Perhaps they should look like this:

collection connections => (
handles => { remember_client => "remember" },
);

That is, the "collection" sub build an attribute that is 'rw', isa
'Reflex::Collection', and instantiates its default value.

Can it instantiate itself lazily?

---

For a larger, longer-term list of todos, please see docs/TODO.otl.
7 changes: 1 addition & 6 deletions eg/eg-34-tcp-server-echo.pl
Expand Up @@ -14,12 +14,7 @@
use Reflex::Collection;
use EchoStream;

has clients => (
is => 'rw',
isa => 'Reflex::Collection',
default => sub { Reflex::Collection->new() },
handles => { remember_client => "remember" },
);
has_many clients => ( handles => { remember_client => "remember" } );

sub on_accept {
my ($self, $args) = @_;
Expand Down
14 changes: 2 additions & 12 deletions eg/eg-42-reflex-in-poe.pl
Expand Up @@ -18,12 +18,7 @@
use Reflex::Collection;
use Reflex::Client;

has connections => (
is => 'rw',
isa => 'Reflex::Collection',
default => sub { Reflex::Collection->new() },
handles => { remember_client => "remember" },
);
has_many clients => ( handles => { remember_client => "remember" } );

sub said {
my ($mybot, $bot_event) = @_;
Expand Down Expand Up @@ -92,12 +87,7 @@
extends 'Reflex::Acceptor';
use Reflex::Collection;

has clients => (
is => 'rw',
isa => 'Reflex::Collection',
default => sub { Reflex::Collection->new() },
handles => { remember_client => "remember" },
);
has_many clients => ( handles => { remember_client => "remember" } );

sub on_accept {
my ($self, $args) = @_;
Expand Down
6 changes: 2 additions & 4 deletions lib/Reflex/Acceptor.pm
Expand Up @@ -35,10 +35,8 @@ Reflex::Acceptor - non-blocking client socket acceptor
use Reflex::Collection;
use EchoStream; # See eg directory.
has clients => (
is => 'rw',
isa => 'Reflex::Collection',
default => sub { Reflex::Collection->new() },
# From Reflex::Collection.
has_many clients => (
handles => { remember_client => "remember" },
);
Expand Down
49 changes: 45 additions & 4 deletions lib/Reflex/Collection.pm
Expand Up @@ -4,10 +4,14 @@

package Reflex::Collection;
use Moose;
use Moose::Exporter;
use Reflex::Callbacks qw(cb_method);
use Carp qw(cluck);

extends 'Reflex::Base';

Moose::Exporter->setup_import_methods( with_caller => [ qw( has_many ) ]);

has objects => (
is => 'rw',
isa => 'HashRef[Reflex::Collectible]',
Expand All @@ -30,6 +34,22 @@ sub cb_forget {
delete $self->objects()->{$args->{_sender}};
}

sub has_many {
my ($caller, $name, %etc) = @_;

my $meta = Class::MOP::class_of($caller);
foreach (qw(is isa default)) {
cluck "has_many is ignoring your '$_' parameter" if exists $etc{$_};
}

$etc{is} = 'ro';
$etc{isa} = 'Reflex::Collection';
$etc{lazy} = 1 unless exists $etc{lazy};
$etc{default} = sub { Reflex::Collection->new() };

$meta->add_attribute($name, %etc);
}

1;

__END__
Expand All @@ -47,10 +67,8 @@ Reflex::Collection - Autmatically manage a collection of collectible objects
use Reflex::Collection;
use EchoStream;
has clients => (
is => 'rw',
isa => 'Reflex::Collection',
default => sub { Reflex::Collection->new() },
# From Reflex::Collection.
has_many clients => (
handles => { remember_client => "remember" },
);
Expand Down Expand Up @@ -90,6 +108,29 @@ TODO - Reflex::Collection is an excellent place to manage pools of
objects. Provide a callback interface for pulling new objects as
needed.
=head2 has_many
Reflex::Collection exports the has_many() function, which works like
Moose's has() with "is", "isa", "lazy" and "default" set to common
values. For example:
has_many connections => (
handles => { remember_connection => "remember" },
);
... is equivalent to:
has connections => (
# Defaults provided by has_many.
is => 'ro',
isa => 'Reflex::Collection',
lazy => 1,
default => sub { Reflex::Collection->new() {,
# Customization.
handles => { remember_connection => "remember" },
);
=head2 new
Create a new Reflex::Collection. It takes no parameters.
Expand Down

0 comments on commit 134c7e0

Please sign in to comment.