Add note about actions in appclass being deprecated
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Upgrading.pod
CommitLineData
8c57b129 1=head1 NAME
2
3Catalyst::Upgrading - Instructions for upgrading to the latest Catalyst
4
7e2ec16e 5=head1 Upgrading to Catalyst 5.80
6
5687c7f9 7Most applications and plugins should run unaltered on Catalyst 5.80.
7e2ec16e 8
8f61d649 9However, a lot of refactoring work has taken place, and several changes have
1a98f036 10been made which could cause incompatibilities. If your application or plugin
8f61d649 11is using deprecated code, or relying on side effects, then you could have
ba03ccca 12issues upgrading to this release.
5687c7f9 13
8f61d649 14Most issues found with pre-existing components have been easy to
15solve. This document provides a complete description of behavior changes
16which may cause compatibility issues, and of new Catalyst warnings which
17be unclear.
7e2ec16e 18
8f61d649 19If you think you have found an upgrade-related issue which is not covered in
20this document, please email the Catalyst list to discuss the problem.
7e2ec16e 21
85f0a66f 22=head1 Moose features
23
8f61d649 24=head2 Application class roles
85f0a66f 25
8f61d649 26You can only apply method modifiers after the application's C<< ->setup >>
85f0a66f 27method has been called. This means that modifiers will not work with methods
28which run during the call to C<< ->setup >>.
29
a6eb852a 30See L<Catalyst::Manual::ExtendingCatalyst> for more information about using
31L<Moose> in your applications.
32
85f0a66f 33=head2 Controller actions in Moose roles
34
8f61d649 35Declaring actions in Roles is currently unsupported.
85f0a66f 36
d935773d 37=head2 Using Moose in Components
38
39The correct way to use Moose in a component in a both forward and backwards
40compatible way is:
41
42 package TestApp::Controller::Root;
43 use Moose;
44 BEGIN { extends 'Catalyst::Component' }; # Or ::Controller, or whatever
45
46See L<Components which inherit from Moose::Object before Catalyst::Component>.
47
8f61d649 48=head1 Known backwards compatibility breakages
7e2ec16e 49
8f61d649 50=head2 Applications in a single file
85f0a66f 51
52Applications must be in their own file, and loaded at compile time. This
8f61d649 53issue generally only affects the tests of CPAN distributions. Your
54application will fail if you try to define an application inline in a
55block, and use plugins which supply a C< new > method, then use that
56application latter in tests within the same file.
85f0a66f 57
58This is due to the fact that Catalyst is inlining a new method on your
8f61d649 59application class allowing it to be compatible with Moose. The method
60used to do this changed in 5.80004 to avoid the possibility of reporting
61an 'Unknown Error' if your application failed to compile.
85f0a66f 62
38f90e49 63=head2 Issues with Class::C3
64
8f61d649 65Catalyst 5.80 uses the L<Algorithm::C3> method dispatch order. This is
66built into Perl 5.10, and comes via L<Class::C3> for Perl 5.8. This
67replaces L<NEXT> with L<Class::C3::Adopt::NEXT>, forcing all components
68to resolve methods using C3, rather than the unpredictable dispatch
69order of L<NEXT>.
38f90e49 70
5d06547d 71This issue is characterised by your application failing to start due to an
72error message about having a non-linear @ISA.
73
8f61d649 74The Catalyst plugin most often causing this is
75L<Catalyst::Plugin::Session::Store::FastMmap> - if you are using this
76plugin and see issues, then please upgrade your plugins, as it has been
77fixed. Note that Makefile.PL in the distribution will warn about known
78incompatible components.
5d06547d 79
80This issue can, however, be found in your own application - the only solution is
81to go through each base class of the class the error was reported against, until
82you identify the ones in conflict, and resolve them.
83
84To be able to generate a linear @ISA, the list of superclasses for each
85class must be resolvable using the C3 algorithm. Unfortunately, when
86superclasses are being used as mixins (to add functionality used in your class),
87and with multiple inheritence, it is easy to get this wrong.
38f90e49 88
89Most common is the case of:
90
91 package Component1; # Note, this is the common case
92 use base qw/Class::Accessor::Fast Class::Data::Inheritable/;
93
8f61d649 94 package Component2; # Accidentally saying it this way causes a failure
38f90e49 95 use base qw/Class::Data::Inheritable Class::Accessor::Fast/;
96
97 package GoesBang;
98 use base qw/Component1 Component2/;
99
5d06547d 100Any situation like this will cause your application to fail to start.
38f90e49 101
8f61d649 102For additional documentation about this issue, and how to resolve it, see
5d06547d 103L<Class::C3::Adopt::NEXT>.
38f90e49 104
6f04e56a 105=head2 Components which inherit from Moose::Object before Catalyst::Component
7e2ec16e 106
6f04e56a 107Moose components which say:
7e2ec16e 108
6f04e56a 109 package TestApp::Controller::Example;
110 use Moose;
845bfcd2 111 extends qw/Moose::Object Catalyst::Component/;
7e2ec16e 112
8f61d649 113to use the constructor provided by Moose, while working (if you do some hacks
1a98f036 114with the C< BUILDARGS > method), will not work with Catalyst 5.80 as
6f04e56a 115C<Catalyst::Component> inherits from C<Moose::Object>, and so C< @ISA > fails
25f61108 116to linearize.
6f04e56a 117
6f04e56a 118The correct way to use Moose in a component in a both forward and backwards
119compatible way is:
120
121 package TestApp::Controller::Root;
122 use Moose;
123 BEGIN { extends 'Catalyst::Component' }; # Or ::Controller, or whatever
124
ba03ccca 125Note that the C< extends > declaration needs to occur in a begin block for
3df46b1b 126L<attributes> to operate correctly.
127
d935773d 128This way you do not inherit directly from C<Moose::Object>
129yourself. Having components which do not inherit their constructor from
130C<Catalyst::Component> is B<unsupported>, and has never been recommended,
131therefore you're on your own if you're using this technique. You'll need
132to detect the version of Catalyst your application is running, and deal
133with it appropriately.
134
eaae9a92 135You also don't get the L<Moose::Object> constructor, and therefore attribute
136initialization will not work as normally expected. If you want to use Moose
3df46b1b 137attributes, then they need to be made lazy to correctly initialize.
138
139Note that this only applies if your component needs to maintain component
140backwards compatibility for Catalyst versions before 5.71001 - in 5.71001
141attributes work as expected, and the BUILD method is called normally
eaae9a92 142(although BUILDARGS is not).
3df46b1b 143
144If you depend on Catalyst 5.8, then B<all> Moose features work as expected.
8566c0de 145
d935773d 146You will also see this issue if you do the following:
147
148 package TestApp::Controller::Example;
149 use Moose;
150 use base 'Catalyst::Controller';
151
152as C< use base > appends to @ISA.
153
e11cac87 154=head3 use Moose in MyApp
155
156Similar to the above, this will also fail:
157
158 package MyApp;
159 use Moose;
160 use Catalyst qw/
161 ConfigLoader
162 /;
163 __PACKAGE__->setup;
164
165If you need to use Moose in your application class (e.g. for method modifiers
8f61d649 166etc.) then the correct technique is:
e11cac87 167
168 package MyApp;
169 use Moose;
5b6f82d2 170 use Catalyst;
171
e11cac87 172 extends 'Catalyst';
5b6f82d2 173
174 __PACKAGE__->config( name => 'MyApp' );
e11cac87 175 __PACKAGE__->setup(qw/
176 ConfigLoader
177 /);
178
04a48104 179=head2 Anonymous closures installed directly into the symbol table
180
181If you have any code which installs anonymous subroutine references directly
182into the symbol table, you may encounter breakages. The simplest solution is
183to use L<Sub::Name> to name the subroutine. Example:
184
e11cac87 185 # Original code, likely to break:
1a98f036 186 my $full_method_name = join('::', $package_name, $method_name);
04a48104 187 *$full_method_name = sub { ... };
188
e11cac87 189 # Fixed Code
04a48104 190 use Sub::Name 'subname';
191 my $full_method_name = join('::',$package_name, $method_name);
192 *$full_method_name = subname $full_method_name, sub { ... };
193
8f61d649 194Additionally, you can take advantage of Catalyst's use of L<Class::MOP> and
195install the closure using the appropriate metaclass. Example:
04a48104 196
197 use Class::MOP;
198 my $metaclass = Moose::Meta::Class->initialize($package_name);
199 $metaclass->add_method($method_name => sub { ... });
200
780654ad 201=head2 Hooking into application setup
202
8f61d649 203To execute code during application start-up, the following snippet in MyApp.pm
780654ad 204used to work:
205
206 sub setup {
207 my ($class, @args) = @_;
208 $class->NEXT::setup(@args);
209 ... # things to do after the actual setup
210 }
211
8f61d649 212With Catalyst 5.80 this won't work anymore, because Catalyst no longer
213uses NEXT.pm for method resolution. The functionality was only ever
214originally operational as L<NEXT> remembers what methods have already
215been called, and will not call them again.
780654ad 216
1a98f036 217Using this now causes infinite recursion between MyApp::setup and
218Catalyst::setup, due to other backwards compatibility issues related to how
219plugin setup works. Moose method modifiers like C<< before|after|around 'setup
220=> sub { ... }; >> also will not operate correctly on the setup method.
780654ad 221
222The right way to do it is this:
223
224 after setup_finalize => sub {
225 ... # things to do after the actual setup
226 };
227
ade00972 228The setup_finalize hook was introduced as a way to avoid this issue.
1a98f036 229
e11cac87 230=head2 Components with a new method which returns false
7e2ec16e 231
8dd2f514 232Previously, if you had a component which inherited from Catalyst::COMPONENT,
8f61d649 233but overrode the new method to return false, then your class's configuration
8dd2f514 234would be blessed into a hash on your behalf, and this would be returned from
a87f5aa5 235the COMPONENT method.
7e2ec16e 236
8f61d649 237This behavior makes no sense, and so has been removed. Implementing your own
238C< new > method in components is B<highly> discouraged. Instead, you should
239inherit the new method from Catalyst::Component, and use Moose's BUILD
1a98f036 240functionality and/or Moose attributes to perform any construction work
241necessary for your class.
7e2ec16e 242
243=head2 __PACKAGE__->mk_accessor('meta');
244
e11cac87 245Won't work due to a limitation of L<Moose>. This is currently being fixed
246inside Moose.
7e2ec16e 247
248=head2 Class::Data::Inheritable side effects
249
8dd2f514 250Previously, writing to a class data accessor would copy the accessor method
251down into your package.
252
8f61d649 253This behavior has been removed. While the class data is still stored
8dd2f514 254per-class, it is stored on the metaclass of the class defining the accessor.
7e2ec16e 255
8f61d649 256Therefore anything relying on the side effect of the accessor being copied down
8dd2f514 257will be broken.
7e2ec16e 258
1a98f036 259The following test demonstrates the problem:
8dd2f514 260
261 {
262 package BaseClass;
263 use base qw/Class::Data::Inheritable/;
264 __PACKAGE__->mk_classdata('foo');
265 }
266
267 {
268 package Child;
269 use base qw/BaseClass/;
270 }
271
272 BaseClass->foo('base class');
273 Child->foo('sub class');
eaae9a92 274
e11cac87 275 use Test::More;
8dd2f514 276 isnt(BaseClass->can('foo'), Child->can('foo'));
7e2ec16e 277
8f61d649 278=head2 Extending Catalyst::Request or other classes in an ad-hoc manner using mk_accessors
7e2ec16e 279
8dd2f514 280Previously, it was possible to add additional accessors to Catalyst::Request
281(or other classes) by calling the mk_accessors class method.
7e2ec16e 282
8f61d649 283This is no longer supported - users should make a subclass of the class whose
284behavior they would like to change, rather than globally polluting the
e11cac87 285Catalyst objects.
8be895a7 286
10011c19 287=head2 Confused multiple inheritance with Catalyst::Component::COMPONENT
8be895a7 288
8f61d649 289Previously, Catalyst's COMPONENT method would delegate to the method on
290the right hand side, which could then delegate back again with
291NEXT. This is poor practice, and in addition, makes no sense with C3
292method dispatch order, and is therefore no longer supported.
bcc773b9 293
ba03ccca 294If a COMPONENT method is detected in the inheritance hierarchy to the right
bcc773b9 295hand side of Catalyst::Component::COMPONENT, then the following warning
296message will be emitted:
7e2ec16e 297
8dd2f514 298 There is a COMPONENT method resolving after Catalyst::Component
5687c7f9 299 in ${next_package}.
8dd2f514 300
8f61d649 301The correct fix is to re-arrange your class's inheritance hierarchy so that the
bcc773b9 302COMPONENT method you would like to inherit is the first (left-hand most)
303COMPONENT method in your @ISA.
7e2ec16e 304
c571d2c8 305=head1 WARNINGS
306
63b546b1 307=head2 Actions in your application class
308
309Having actions in your application class will now emit a warning at application
310startup as this is deprecated. It is highly recommended that these actions are moved
311into a MyApp::Controller::Root (as demonstrated by the scaffold application
312generated by catalyst.pl)
313
ade00972 314=head2 Catalyst::Base
315
8f61d649 316Any code using L<Catalyst::Base> will now emit a warning; this
317module will be removed in a future release.
ade00972 318
c571d2c8 319=head2 Methods in Catalyst::Dispatcher
320
8f61d649 321The following methods in Catalyst::Dispatcher are implementation
322details, which may change in the 5.8X release series, and therefore their use
bcc773b9 323is highly deprecated.
c571d2c8 324
325=over
326
8dd2f514 327=item tree
c571d2c8 328
8dd2f514 329=item dispatch_types
c571d2c8 330
8dd2f514 331=item registered_dispatch_types
c571d2c8 332
8dd2f514 333=item method_action_class
c571d2c8 334
8dd2f514 335=item action_hash
c571d2c8 336
337=item container_hash
338
339=back
340
341The first time one of these methods is called, a warning will be emitted:
7e2ec16e 342
bcc773b9 343 Class $class is calling the deprecated method Catalyst::Dispatcher::$public_method_name,
344 this will be removed in Catalyst 5.9X
7e2ec16e 345
c571d2c8 346You should B<NEVER> be calling any of these methods from application code.
347
8f61d649 348Plugin authors and maintainers whose plugins currently call these methods
8f5a2bd9 349should change to using the public API, or, if you do not feel the public API
8f61d649 350adequately supports your use case, please email the development list to
8f5a2bd9 351discuss what API features you need so that you can be appropriately supported.
7e2ec16e 352
95b20422 353=head2 Class files with names that don't correspond to the packages they define
7e2ec16e 354
e11cac87 355In this version of Catalyst, if a component is loaded from disk, but no
ba03ccca 356symbols are defined in that component's name space after it is loaded, this
bcc773b9 357warning will be issued:
7e2ec16e 358
bcc773b9 359 require $class was successful but the package is not defined.
7e2ec16e 360
8f61d649 361This is to protect against confusing bugs caused by mistyping package names,
bcc773b9 362and will become a fatal error in a future version.
363
364Please note that 'inner packages' (via L<Devel::InnerPackage>) are still fully
8f61d649 365supported; this warning is only issued when component file naming does not map
bcc773b9 366to B<any> of the packages defined within that component.
7e2ec16e 367
5687c7f9 368=head2 $c->plugin method
369
25f61108 370Calling the plugin method is deprecated, and calling it at run time is B<highly
8dd2f514 371deprecated>.
7e2ec16e 372
8dd2f514 373Instead you are recommended to use L< Catalyst::Model::Adaptor > or similar to
ba03ccca 374compose the functionality you need outside of the main application name space.
7e2ec16e 375
4e68badc 376Calling the plugin method will not be supported past Catalyst 5.81.
bcc773b9 377
7e2ec16e 378=cut
4e68badc 379