Catalyst::Upgrading - Instructions for upgrading to the latest Catalyst
+=head1 Upgrading to Catalyst 5.90090
+
+L<Catalyst::Utils> has a new method 'inject_component' which works the same as the method of
+the same name in L<CatalystX::InjectComponent>. You should start converting any
+use of the non core method in your code as future changes to Catalyst will be
+sychronized to the core method first. We reserve the right to cease support
+of the non core version should we reach a point in time where it cannot be
+properly supported as an external module. Luckily this should be a trivial
+search and replace. Change all occurances of:
+
+ CatalystX::InjectComponent->inject(...)
+
+Into
+
+ Catalyst::Utils::inject_component(...)
+
+and we expect everything to work the same (we'd consider it not working the same
+to be a bug, and please report it.)
+
+We also cored features from L<CatalystX::RoleApplicator> to compose a role into the
+request, response and stats classes. The main difference is that with L<CatalystX::RoleApplicator>
+you did:
+
+ package MyApp;
+
+ use Catalyst;
+ use CatalystX::RoleApplicator;
+
+ __PACKAGE__->apply_request_class_roles(
+ qw/My::Request::Role Other::Request::Role/);
+
+Whereas now we have three class attributes, 'request_class_traits', 'response_class_traits'
+and 'stats_class_traits', so you use like this (note this value is an ArrayRef)
+
+
+ package MyApp;
+
+ use Catalyst;
+
+ __PACKAGE__->request_class_traits([qw/
+ My::Request::Role
+ Other::Request::Role/]);
+
+(And the same for response_class_traits and stats_class_traits. We left off the
+traits for Engine, since that class does a lot less nowadays, and dispatcher. If you
+used those and can share a use case, we'd be likely to support them.
+
+Lastly, we have some of the feature from L<CatalystX::ComponentsFromConfig> in
+core. This should mostly work the same way in core, except for now the
+core version does not create an automatic base wrapper class for your configured
+components (it requires these to be catalyst components and injects them directly.
+So if you make heavy use of custom base classes in L<CatalystX::ComponentsFromConfig>
+you might need a bit of work to use the core version (although there is no reason
+to stop using L<CatalystX::ComponentsFromConfig> since it should continue to work
+fine and we'd consider issues with it to be bugs). Here's one way to map from
+L<CatalystX::ComponentsFromConfig> to core:
+
+In L<CatalystX::ComponentsFromConfig>:
+
+ MyApp->config(
+ 'Model::MyClass' => {
+ class => 'MyClass',
+ args => { %args },
+
+ });
+
+and now in core:
+
+ MyApp->config(
+ inject_components => {
+ 'Model::MyClass' => { from_component => 'My::Class' },
+ },
+ 'Model::MyClass' => {
+ %args
+ },
+ );
+
+Although the cored behavior requires more code, its better separates concerns
+as well as plays more into core Catalyst expections of how configuration shoul
+look.
+
+Also we added a new develop console mode only warning when you call a component
+with arguments that don't expect or do anything meaningful with those args. Its
+possible if you are logging debug mode in production (please don't...) this
+could add verbosity to those logs if you also happen to be calling for components
+and passing pointless arguments. We added this warning to help people not make this
+error and to better understand the component resolution flow.
+
+=head1 Upgrading to Catalyst 5.90085
+
+In this version of Catalyst we made a small change to Chained Dispatching so
+that when two or more actions all have the same path specification AND they
+all have Args(0), we break the tie by choosing the last action defined, and
+not the first one defined. This was done to normalize Chaining to following
+the 'longest Path wins, and when several actions match the same Path specification
+we choose the last defined.' rule. Previously Args(0) was hard coded to be a special
+case such that the first action defined would match (which is not the case when
+Args is not zero.)
+
+Its possible that this could be a breaking change for you, if you had used
+action roles (custom or otherwise) to add additional matching rules to differentiate
+between several Args(0) actions that share the same root action chain. For
+example if you have code now like this:
+
+ sub check_default :Chained(/) CaptureArgs(0) { ... }
+
+ sub default_get :Chained('check_default') PathPart('') Args(0) GET {
+ pop->res->body('get3');
+ }
+
+ sub default_post :Chained('check_default') PathPart('') Args(0) POST {
+ pop->res->body('post3');
+ }
+
+ sub chain_default :Chained('check_default') PathPart('') Args(0) {
+ pop->res->body('chain_default');
+ }
+
+The way that chaining will work previous is that when two or more equal actions can
+match, the 'top' one wins. So if the request is "GET .../check_default" BOTH
+actions 'default_get' AND 'chain_default' would match. To break the tie in
+the case when Args is 0, we'd previous take the 'top' (or first defined) action.
+Unfortunately this treatment of Args(0) is special case. In all other cases
+we choose the 'last defined' action to break a tie. So this version of
+Catalyst changed the dispatcher to make Args(0) no longer a special case for
+breaking ties. This means that the above code must now become:
+
+ sub check_default :Chained(/) CaptureArgs(0) { ... }
+
+ sub chain_default :Chained('check_default') PathPart('') Args(0) {
+ pop->res->body('chain_default');
+ }
+
+ sub default_get :Chained('check_default') PathPart('') Args(0) GET {
+ pop->res->body('get3');
+ }
+
+ sub default_post :Chained('check_default') PathPart('') Args(0) POST {
+ pop->res->body('post3');
+ }
+
+If we want it to work as expected (for example we we GET to match 'default_get' and
+POST to match 'default_post' and any other http Method to match 'chain_default').
+
+In other words Arg(0) and chained actions must now follow the normal rule where
+in a tie the last defined action wins and you should place all your less defined
+or 'catch all' actions first.
+
+If this causes you trouble and you can't fix your code to conform, you may set the
+application configuration setting "use_chained_args_0_special_case" to true and
+that will revert you code to the previous behavior.
+
+=head2 More backwards compatibility options with UTF-8 changes
+
+In order to give better backwards compatiblity with the 5.90080+ UTF-8 changes
+we've added several configuration options around control of how we try to decode
+your URL keywords / query parameters.
+
+C<do_not_decode_query>
+
+If true, then do not try to character decode any wide characters in your
+request URL query or keywords. Most readings of the relevent specifications
+suggest these should be UTF-* encoded, which is the default that L<Catalyst>
+will use, hwoever if you are creating a lot of URLs manually or have external
+evil clients, this might cause you trouble. If you find the changes introduced
+in Catalyst version 5.90080+ break some of your query code, you may disable
+the UTF-8 decoding globally using this configuration.
+
+This setting takes precedence over C<default_query_encoding> and
+C<decode_query_using_global_encoding>
+
+C<default_query_encoding>
+
+By default we decode query and keywords in your request URL using UTF-8, which
+is our reading of the relevent specifications. This setting allows one to
+specify a fixed value for how to decode your query. You might need this if
+you are doing a lot of custom encoding of your URLs and not using UTF-8.
+
+This setting take precedence over C<decode_query_using_global_encoding>.
+
+C<decode_query_using_global_encoding>
+
+Setting this to true will default your query decoding to whatever your
+general global encoding is (the default is UTF-8).
+
+
+=head1 Upgrading to Catalyst 5.90080
+
+UTF8 encoding is now default. For temporary backwards compatibility, if this
+change is causing you trouble, you can disable it by setting the application
+configuration option to undef:
+
+ MyApp->config(encoding => undef);
+
+But please consider this a temporary measure since it is the intention that
+UTF8 is enabled going forwards and the expectation is that other ecosystem
+projects will assume this as well. At some point you application will not
+correctly function without this setting.
+
+As of 5.90084 we've added two additional configuration flags for more selective
+control over some encoding changes: 'skip_body_param_unicode_decoding' and
+'skip_complex_post_part_handling'. You may use these to more selectively
+disable new features while you are seeking a long term fix. Please review
+CONFIGURATION in L<Catalyst>.
+
+For further information, please see L<Catalyst::UTF8>
+
+A number of projects in the wider ecosystem required minor updates to be able
+to work correctly. Here's the known list:
+
+L<Catalyst::View::TT>, L<Catalyst::View::Mason>, L<Catalyst::View::HTML::Mason>,
+L<Catalyst::View::Xslate>, L<Test::WWW::Mechanize::Catalyst>
+
+You will need to update to modern versions in most cases, although quite a few
+of these only needed minor test case and documentation changes so you will need
+to review the changelog of each one that is relevant to you to determine your
+true upgrade needs.
+
+=head1 Upgrading to Catalyst 5.90060
+
+Starting in the v5.90059_001 development release, the regexp dispatch type is
+no longer automatically included as a dependency. If you are still using this
+dispatch type, you need to add L<Catalyst::DispatchType::Regex> into your build
+system.
+
+The standalone distribution of Regexp will be supported for the time being, but
+should we find that supporting it prevents us from moving L<Catalyst> forward
+in necessary ways, we reserve the right to drop that support. It is highly
+recommended that you use this last stage of deprecation to change your code.
+
+=head1 Upgrading to Catalyst 5.90040
+
+=head2 Catalyst::Plugin::Unicode::Encoding is now core
+
+The previously stand alone Unicode support module L<Catalyst::Plugin::Unicode::Encoding>
+has been brought into core as a default plugin. Going forward, all you need is
+to add a configuration setting for the encoding type. For example:
+
+ package Myapp::Web;
+
+ use Catalyst;
+
+ __PACKAGE__->config( encoding => 'UTF-8' );
+
+Please note that this is different from the old stand alone plugin which applied
+C<UTF-8> encoding by default (that is, if you did not set an explicit
+C<encoding> configuration value, it assumed you wanted UTF-8). In order to
+preserve backwards compatibility you will need to explicitly turn it on via the
+configuration setting. THIS MIGHT CHANGE IN THE FUTURE, so please consider
+starting to test your application with proper UTF-8 support and remove all those
+crappy hacks you munged into the code because you didn't know the Plugin
+existed :)
+
+For people that are using the Plugin, you will note a startup warning suggesting
+that you can remove it from the plugin list. When you do so, please remember to
+add the configuration setting, since you can no longer rely on the default being
+UTF-8. We'll add it for you if you continue to use the stand alone plugin and
+we detect this, but this backwards compatibility shim will likely be removed in
+a few releases (trying to clean up the codebase after all).
+
+If you have trouble with any of this, please bring it to the attention of the
+Catalyst maintainer group.
+
+=head2 basic async and event loop support
+
+This version of L<Catalyst> offers some support for using L<AnyEvent> and
+L<IO::Async> event loops in your application. These changes should work
+fine for most applications however if you are already trying to perform
+some streaming, minor changes in this area of the code might affect your
+functionality. Please see L<Catalyst::Response\write_fh> for more and for a
+basic example.
+
+We consider this feature experimental. We will try not to break it, but we
+reserve the right to make necessary changes to fix major issues that people
+run into when the use this functionality in the wild.
+
+=head1 Upgrading to Catalyst 5.90030
+
+=head2 Regex dispatch type is deprecated.
+
+The Regex dispatchtype (L<Catalyst::DispatchType::Regex>) has been deprecated.
+
+You are encouraged to move your application to Chained dispatch (L<Catalyst::DispatchType::Chained>).
+
+If you cannot do so, please add a dependency to Catalyst::DispatchType::Regex to your application's
+Makefile.PL
+
=head1 Upgrading to Catalyst 5.9
The major change is that L<Plack>, a toolkit for using the L<PSGI>
The engines that are built upon the various iterations of mod_perl,
L<Catalyst::Engine::Apache::MP13> (for mod_perl 1, and Apache 1.x) and
L<Catalyst::Engine::Apache2::MP20> (for mod_perl 2, and Apache 2.x),
-should be seamless upgrades and will work using using L<Plack::Handler::Apache1>
+should be seamless upgrades and will work using L<Plack::Handler::Apache1>
or L<Plack::Handler::Apache2> as required.
L<Catalyst::Engine::Apache2::MP19>, however, is no longer supported, as
COMPONENT method you would like to inherit is the first (left-hand most)
COMPONENT method in your @ISA.
+=head2 Development server relying on environment variables
+
+Previously, the development server would allow propagation of system
+environment variables into the request environment, this has changed with the
+adoption of Plack. You can use L<Plack::Middleware::ForceEnv> to achieve the
+same effect.
+
=head1 WARNINGS
=head2 Actions in your application class
Having actions in your application class will now emit a warning at application
startup as this is deprecated. It is highly recommended that these actions are moved
into a MyApp::Controller::Root (as demonstrated by the scaffold application
-generated by catalyst.pl).
+generated by catalyst.pl).
This warning, also affects tests. You should move actions in your test,
creating a myTest::Controller::Root, like the following example:
sub action : Local {
my ( $self, $c ) = @_;
- $c->do_something;
+ $c->do_something;
}
1;