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