diff options
author | groditi <groditi@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7> | 2008-11-11 21:08:20 +0000 |
---|---|---|
committer | groditi <groditi@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7> | 2008-11-11 21:08:20 +0000 |
commit | 747a1feb2d49d2dba85f997fa2f4542a17800331 (patch) | |
tree | bd1d5330d907dff7befe227f1bcdd20b7ef911ed | |
parent | 7ea45b2aff36dd61953b1517a1cfb079dcea230c (diff) | |
download | reaction-747a1feb2d49d2dba85f997fa2f4542a17800331.tar.gz reaction-747a1feb2d49d2dba85f997fa2f4542a17800331.zip |
fix leaks via make_context_closure
-rw-r--r-- | lib/Reaction/UI/Controller.pm | 8 | ||||
-rw-r--r-- | lib/Reaction/UI/Controller/Collection/CRUD.pm | 30 |
2 files changed, 24 insertions, 14 deletions
diff --git a/lib/Reaction/UI/Controller.pm b/lib/Reaction/UI/Controller.pm index 76b562e..fc2f597 100644 --- a/lib/Reaction/UI/Controller.pm +++ b/lib/Reaction/UI/Controller.pm @@ -7,6 +7,7 @@ use base qw( ); use Reaction::Class; +use Scalar::Util 'weaken'; sub push_viewport { my $self = shift; @@ -73,6 +74,13 @@ sub redirect_to { $c->res->redirect($uri); } +sub make_context_closure { + my($self, $closure) = @_; + my $ctx = $self->context; + weaken $ctx; + return sub { $closure->($ctx, @_) }; +} + 1; __END__; diff --git a/lib/Reaction/UI/Controller/Collection/CRUD.pm b/lib/Reaction/UI/Controller/Collection/CRUD.pm index 1d8e4cc..352b142 100644 --- a/lib/Reaction/UI/Controller/Collection/CRUD.pm +++ b/lib/Reaction/UI/Controller/Collection/CRUD.pm @@ -34,61 +34,63 @@ sub get_model_action { my ($self, $c, $name, $target) = @_; return $target->action_for($name, ctx => $c); } - sub create :Chained('base') :PathPart('create') :Args(0) { my ($self, $c) = @_; + my $apply = sub { $self->after_create_callback( @_) }; + my $close = sub { $self->on_create_close_callback( @_) }; my $vp_args = { - on_apply_callback => sub { $self->after_create_callback( @_); }, - on_close_callback => sub { $self->on_create_close_callback( @_) } + on_apply_callback => $self->make_context_closure($apply), + on_close_callback => $self->make_context_closure($close), }; $self->basic_model_action( $c, $vp_args); } sub delete_all :Chained('base') :PathPart('delete_all') :Args(0) { my ($self, $c) = @_; + my $close = sub { $self->on_delete_all_close_callback( @_) }; $self->basic_model_action( $c, { - on_close_callback => sub { $self->on_delete_all_close_callback( @_) } + on_close_callback => $self->make_context_closure($close), }); } sub on_delete_all_close_callback { - my($self) = @_; - $self->redirect_to($self->context, 'list'); + my($self, $c) = @_; + $self->redirect_to($c, 'list'); } sub after_create_callback { - my ($self, $vp, $result) = @_; - my $c = $self->context; + my ($self, $c, $vp, $result) = @_; return $self->redirect_to ( $c, 'update', [ @{$c->req->captures}, $result->id ] ); } sub on_create_close_callback { my($self, $c, $vp) = @_; - $self->redirect_to( $self->context, 'list' ); + $self->redirect_to( $c, 'list' ); } sub update :Chained('object') :Args(0) { my ($self, $c) = @_; + my $close = sub { $self->on_update_close_callback( @_) }; my $vp_args = { - on_close_callback => sub { $self->on_update_close_callback( @_ ) } + on_close_callback => $self->make_context_closure($close), }; $self->basic_model_action( $c, $vp_args); } sub on_update_close_callback { - my($self) = @_; + my($self, $c) = @_; #this needs a better solution. currently thinking about it - my $c = $self->context; - my @cap = @{ $c->req->captures }; + my @cap = @{$c->req->captures}; pop(@cap); # object id $self->redirect_to($c, 'list', \@cap); } sub delete :Chained('object') :Args(0) { my ($self, $c) = @_; + my $close = sub { $self->on_update_close_callback( @_) }; my $vp_args = { - on_close_callback => sub { $self->on_update_close_callback( @_) } + on_close_callback => $self->make_context_closure($close), }; $self->basic_model_action( $c, $vp_args); } |