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