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