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