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