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