File Coverage

blib/lib/Catalyst/Component/WithDelayedSetup.pm
Criterion Covered Total %
statement 10 10 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod 0 1 0.0
total 14 15 93.3


line stmt bran cond sub pod time code
1             package Catalyst::Component::WithDelayedSetup;
2              
3 1     1   10771 use Moose::Role;
  1         2  
  1         7  
4             our $VERSION = '0.002';
5              
6             {
7             package Catalyst::Component::Deferred;
8              
9 1     1   3614 use Moose;
  1         1  
  1         5  
10              
11             has setup => (is=>'ro', required=>1, isa=>'CodeRef');
12              
13             has target => (
14             is => 'ro',
15             init_arg => undef,
16             lazy => 1,
17             isa => 'Object',
18             required => 1,
19             default => sub { shift->setup->() } );
20              
21 5     5 0 87544 sub ACCEPT_CONTEXT { return shift->target }
22             }
23              
24 1     1   4116 use Catalyst::Component::Deferred;
  1         1  
  1         124  
25              
26             around 'COMPONENT', sub {
27             my ($orig, $class, @args) = @_;
28             return Catalyst::Component::Deferred
29             ->new( setup => sub { $class->$orig(@args) });
30             };
31              
32             1;
33              
34             =head1 NAME
35              
36             Catalyst::Component::WithDelayedSetup - Moose Role for components which setup late
37              
38             =head1 SYNOPSIS
39              
40             package MyApp::Model::Foo;
41              
42             use Moose;
43             extends 'Catalyst::Model';
44             with 'Catalyst::Component::DelayedSetup';
45              
46             # Proceed as normal
47              
48             =head1 DESCRIPTION
49              
50             Sometimes you want an application scoped component that nevertheless needs other
51             application components as part of its setup. In the past this was not reliable
52             since Application scoped components are setup in linear order. You could not
53             call $app->model('A') in a COMPONENT method and expect $app->model('B') to be there
54             This role defers creating the application scoped instance until after your application is
55             fully setup. This means you can now assume your other application scoped components
56             (components that do COMPONENT but not ACCEPT_CONTEXT) are available as dependencies.
57              
58             Please note this means that your instance is not created until the first time its
59             called in a request. As a result any errors with configuration will not show up
60             until later in runtime. So there is a larger burden on your testing to make sure
61             your application startup and runtime is accurate. Also note that even though your
62             instance creation is deferred to request time, the request context is NOT given,
63             but the application is (this means that you cannot depend on components that do
64             ACCEPT_CONTEXT, since you don't have one...).
65              
66             Please note it makes no sense to use this component role and then do the ACCEPT_CONTEXT
67             method...
68              
69             =head1 SEE ALSO
70              
71             L<Catalyst::Component>, L<Catalyst>.
72              
73             =head1 AUTHOR
74            
75             John Napiorkowski L<email:jjnapiork@cpan.org>
76            
77             =head1 COPYRIGHT & LICENSE
78            
79             Copyright 2015, John Napiorkowski L<email:jjnapiork@cpan.org>
80            
81             This library is free software; you can redistribute it and/or modify it under
82             the same terms as Perl itself.
83              
84             =cut