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