Commit | Line | Data |
8a101890 |
1 | =head1 NAME |
2 | |
3 | Catalyst::Manual::CatalystAndMoose - How Catalyst 5.8+ and Moose relate |
4 | |
5 | |
6 | =head1 DESCRIPTION |
7 | |
8 | Since version 5.8 the core of Catalyst is based on L<Moose>. Although |
9 | the developers went through great lengths to allow for a seamless |
10 | transition, there are still a few things to keep in mind when trying |
11 | to exploit the power of L<Moose> in your Catalyst application. |
12 | |
13 | This document provides you with a short overview of common caveats and |
14 | best practices to use L<Moose>-based classes within Catalyst. |
15 | |
16 | |
17 | =head1 THE CONTEXT CLASS |
18 | |
19 | A Moose-ified version of the context class should look like this: |
20 | |
21 | package MyApp; |
22 | |
23 | use Moose; |
4d719c7e |
24 | use namespace::autoclean; |
25 | use Catalyst ( |
8a101890 |
26 | # your roles and plugins |
27 | ); |
28 | |
4d719c7e |
29 | $app->config( name => 'MyApp' ); |
30 | $app->setup; |
31 | |
8a101890 |
32 | # method modifiers must be created after setup because otherwise they will |
33 | # conflict with plugin overrides |
34 | |
35 | after 'finalize' => sub{ |
36 | my $c = shift; |
37 | $c->log->info( 'done!' ); |
38 | } |
39 | |
40 | You should also be aware, that roles in C<< $c->setup >> are applied |
41 | after the last plugin with all the benefits of using a single C<< |
4d719c7e |
42 | with() >> statement in an ordinary L<Moose> class. |
43 | |
44 | Your class is automatically made immutable at the end of the current file. |
8a101890 |
45 | |
4d719c7e |
46 | CAVEAT: Using roles in C<< $c->setup >> was implemented in Catalyst |
8a101890 |
47 | version 5.80004. In prior versions you might get away with |
48 | |
49 | after 'setup_plugins' => sub{ with( |
50 | # your roles |
51 | )}; |
52 | |
53 | $app->setup( |
54 | # your plugins |
55 | ); |
56 | |
57 | but this is discouraged and you should upgrade to 5.80004 anyway, |
58 | because it fixes a few important regression against 5.71 |
59 | |
4d719c7e |
60 | CAVEAT: Using roles in C<< $c->setup >> will not currently allow |
61 | you to pass parameters to roles, or perform conflict resolution. |
62 | Conflict detection still works as expected. |
8a101890 |
63 | |
64 | =head2 ACCESSORS |
65 | |
d237e058 |
66 | Most of the request-specific attributes like C<$c->stash>, |
8a101890 |
67 | C<$c->request> and C<$c->response> have been converted to |
68 | L<Moose> attributes but without type constraints, attribute helpers or |
69 | builder methods. This ensures that Catalyst 5.8 is fully backwards |
70 | compatible to applications using the published API of Catalyst 5.7 but |
71 | slightly limits the gains that could be had by wielding the full power |
72 | of L<Moose> attributes. |
73 | |
74 | Most of the accessors to information gathered during compile time is |
75 | managed by C<Catalyst::ClassData>, which is a L<Moose>-aware version |
76 | of L<Class::Data::Inheritable> but not compatible with |
77 | L<MooseX::ClassAttribute>. |
78 | |
79 | |
80 | =head2 ROLES AND METHOD MODIFIERS |
81 | |
82 | Since the release of Catalyst version 5.8 the only reason for creating |
83 | a Catalyst extension as a plugin is to provide backward compatibility |
4d719c7e |
84 | to applications still using version 5.7. |
8a101890 |
85 | |
86 | If backward compatibility is of no concern to you, you could as easily |
87 | rewrite your plugins as roles and enjoy all the benefits of automatic |
88 | method re-dispatching of C<< before >> and C<< after >> method |
89 | modifiers, naming conflict detecting and generally cleaner code. |
90 | |
91 | Plugins and roles should never use |
92 | |
93 | after 'setup' => sub { ... } # wrong |
94 | |
95 | but rely on |
96 | |
97 | after 'setup_finalize' => sub { ... } # this will work |
98 | |
99 | to run their own setup code if needed. If they need to influence the |
100 | setup process itself, they can modify C<< setup_dispatcher() >>, |
101 | C<< setup_engine()>>, C<< setup_stats() >>, C<< setup_components() >> |
102 | and C<< setup_actions() >>, but this should be done with due |
103 | consideration and as late as possible. |
104 | |
8a101890 |
105 | =head1 CONTROLLERS |
106 | |
107 | To activate Catalyst's action attributes, Moose-ified controller |
108 | classes need to extend L<Catalyst::Controller> at compile time before |
109 | the actions themselves are declared: |
110 | |
111 | package Catalyst::Controller::Root; |
8a101890 |
112 | use Moose; |
4d719c7e |
113 | use namespace::autoclean; |
114 | |
115 | BEGIN { extends 'Catalyst::Controller'; } |
116 | with qw( |
8a101890 |
117 | # your controller roles |
118 | ); |
8a101890 |
119 | |
4d719c7e |
120 | =head2 Controller Roles |
121 | |
122 | It is possible to use roles to apply method modifiers on controller actions |
123 | from 5.80003 onwards, or use modifiers in actions in your controller classes |
124 | themselves. |
125 | |
126 | It is possible to have action methods with attributes inside Moose roles, using |
127 | the trait introduced in L<MooseX::MethodAttributes> version 0.12, example: |
128 | |
129 | package MyApp::ControllerRole; |
130 | use Moose::Role -traits => 'MethodAttributes'; |
131 | use namespace::autoclean; |
132 | |
133 | sub foo : Local { |
134 | my ($self, $c) = @_; |
135 | ... |
136 | } |
137 | |