Browse files

Add the capability for an object member (attribute) to emit messages …

…when altered.
  • Loading branch information...
1 parent f7ac916 commit 7301d96c36673da8671129b3135f5e43f2106e9c @rcaputo committed Aug 22, 2009
Showing with 107 additions and 0 deletions.
  1. +40 −0 docs/EmitterTrait.pm
  2. +67 −0 docs/eg-09-emitter-trait.pl
View
40 docs/EmitterTrait.pm
@@ -0,0 +1,40 @@
+package EmitterTrait;
+use Moose::Role;
+use Scalar::Util qw(weaken);
+
+has trigger => (
+ is => 'ro',
+ default => sub {
+ my $meta_self = shift;
+
+ # $meta_self->name() is not set yet.
+ # Weaken $meta_self so that the closure isn't fatal.
+ weaken $meta_self;
+
+ sub {
+ my ($self, $value) = @_;
+
+ $self->emit(
+ args => {
+ value => $value,
+ },
+ event => $self->meta->get_attribute($meta_self->name())->event(),
+ );
+ }
+ }
+);
+
+has event => (
+ isa => 'Str',
+ is => 'ro',
+ lazy => 1,
+ default => sub {
+ my $self = shift;
+ return $self->name();
+ },
+);
+
+package Moose::Meta::Attribute::Custom::Trait::Emitter;
+sub register_implementation { 'EmitterTrait' }
+
+1;
View
67 docs/eg-09-emitter-trait.pl
@@ -0,0 +1,67 @@
+#!/usr/bin/perl
+
+# Objects may emit events when their members are changed.
+
+{
+ package Counter;
+ use Moose;
+ extends 'Stage';
+ use Delay;
+ use ObserverTrait;
+ use EmitterTrait;
+
+ has count => (
+ traits => ['Emitter'],
+ isa => 'Int',
+ is => 'rw',
+ default => 0,
+ );
+
+ has ticker => (
+ traits => ['Observer'],
+ isa => 'Delay|Undef',
+ is => 'rw',
+ );
+
+ sub BUILD {
+ my $self = shift;
+
+ $self->ticker(
+ Delay->new(
+ interval => 1,
+ auto_repeat => 1,
+ )
+ );
+ }
+
+ sub on_ticker_tick {
+ my $self = shift;
+ $self->count($self->count() + 1);
+ }
+}
+
+{
+ package Watcher;
+ use Moose;
+ extends 'Stage';
+
+ has counter => (
+ traits => ['Observer'],
+ isa => 'Counter',
+ is => 'rw',
+ );
+
+ sub BUILD {
+ my $self = shift;
+ $self->counter(Counter->new());
+ }
+
+ sub on_counter_count {
+ my ($self, $args) = @_;
+ warn "Watcher sees counter count: $args->{value}\n";
+ }
+}
+
+my $w = Watcher->new();
+Stage->run_all();
+exit;

0 comments on commit 7301d96

Please sign in to comment.