File Coverage

blib/lib/Catalyst/Component/ContextClosure.pm
Criterion Covered Total %
statement 9 13 69.2
branch n/a
condition n/a
subroutine 3 5 60.0
pod 1 1 100.0
total 13 19 68.4


line stmt bran cond sub pod time code
1             package Catalyst::Component::ContextClosure;
2              
3 80     80   1150440 use Moose::Role;
  80         267  
  80         914  
4 80     80   454632 use Scalar::Util 'weaken';
  80         305  
  80         6879  
5 80     80   724 use namespace::clean -except => [ 'meta' ];
  80         251  
  80         1107  
6              
7             sub make_context_closure {
8 0     0 1   my ($self, $closure, $ctx) = @_;
9 0           weaken $ctx;
10 0     0     return sub { $closure->($ctx, @_) };
  0            
11             }
12              
13             1;
14              
15             __END__
16              
17             =head1 NAME
18              
19             Catalyst::Component::ContextClosure - Moose Role for components which need to close over the $ctx, without leaking
20              
21             =head1 SYNOPSIS
22              
23             package MyApp::Controller::Foo;
24             use Moose;
25             use namespace::clean -except => 'meta';
26             BEGIN {
27             extends 'Catalyst::Controller';
28             with 'Catalyst::Component::ContextClosure';
29             }
30              
31             sub some_action : Local {
32             my ($self, $ctx) = @_;
33             $ctx->stash(a_closure => $self->make_context_closure(sub {
34             my ($ctx) = @_;
35             $ctx->response->body('body set from closure');
36             }, $ctx));
37             }
38              
39             =head1 DESCRIPTION
40              
41             A common problem with stashing a closure, that closes over the Catalyst context
42             (often called C<$ctx> or C<$c>), is the circular reference it creates, as the
43             closure holds onto a reference to context, and the context holds a reference to
44             the closure in its stash. This creates a memory leak, unless you always
45             carefully weaken the closures context reference.
46              
47             This role provides a convenience method to create closures, that closes over
48             C<$ctx>.
49              
50             =head1 METHODS
51              
52             =head2 make_context_closure ($closure, $ctx)
53              
54             Returns a code reference, that will invoke C<$closure> with a weakened
55             reference to C<$ctx>. All other parameters to the returned code reference will
56             be passed along to C<$closure>.
57              
58             =head1 SEE ALSO
59              
60             L<Catalyst::Component>
61              
62             L<Catalyst::Controller>
63              
64             L<CatalystX::LeakChecker>
65              
66             =begin stopwords
67              
68             =head1 AUTHOR
69              
70             Florian Ragwitz <rafl@debian.org>
71              
72             =end stopwords
73              
74             =head1 COPYRIGHT
75              
76             This library is free software. You can redistribute it and/or modify it under
77             the same terms as Perl itself.
78              
79             =cut