use strict;
use warnings;
use inc::Module::Install 0.87;
- BEGIN { # Make it easy for newbies
- if ($Module::Install::AUTHOR) {
- require Module::Install::AuthorRequires;
- require Module::Install::CheckConflicts;
- require Module::Install::AuthorTests;
- }
+ { # Ensure that these get used - yes, M::I loads them for us, but if you're
+ # in author mode and don't have them installed, then the error is tres
+ # cryptic.
+ no warnings 'redefine';
+ use Module::Install::AuthorRequires;
+ use Module::Install::CheckConflicts;
+ use Module::Install::AuthorTests;
}
+
perl_version '5.008004';
name 'Catalyst-Runtime';
all_from 'lib/Catalyst/Runtime.pm';
requires 'List::MoreUtils';
- requires 'namespace::autoclean';
+ requires 'namespace::autoclean' => '0.09';
requires 'namespace::clean';
+requires 'namespace::autoclean';
requires 'B::Hooks::EndOfScope' => '0.08';
- requires 'MooseX::Emulate::Class::Accessor::Fast' => '0.00801';
+ requires 'MooseX::Emulate::Class::Accessor::Fast' => '0.00903';
requires 'Class::MOP' => '0.83';
- requires 'Moose' => '0.78';
- requires 'MooseX::MethodAttributes::Inheritable' => '0.15';
+ requires 'Moose' => '0.90';
+ requires 'MooseX::MethodAttributes::Inheritable' => '0.17';
+ requires 'MooseX::Role::WithOverloading';
requires 'Carp';
requires 'Class::C3::Adopt::NEXT' => '0.07';
requires 'CGI::Simple::Cookie';
requires 'HTML::Entities';
requires 'HTTP::Body' => '1.04'; # makes uploadtmp work
requires 'HTTP::Headers' => '1.64';
- requires 'HTTP::Request';
- requires 'HTTP::Response';
+ requires 'HTTP::Request' => '5.814';
+ requires 'HTTP::Response' => '5.813';
requires 'HTTP::Request::AsCGI' => '0.8';
requires 'LWP::UserAgent';
requires 'Module::Pluggable' => '3.9';
requires 'Task::Weaken';
requires 'Text::Balanced'; # core in 5.8.x but mentioned for completeness
requires 'MRO::Compat';
+requires 'MooseX::Getopt';
+requires 'MooseX::Types';
requires 'String::RewritePrefix' => '0.004'; # Catalyst::Utils::resolve_namespace
-recommends 'B::Hooks::OP::Check::StashChange';
-
test_requires 'Class::Data::Inheritable';
test_requires 'Test::Exception';
+ test_requires 'Test::More' => '0.88';
# aggregate tests if AGGREGATE_TESTS is set and a recent Test::Aggregate and a Test::Simple it works with is available
if ($ENV{AGGREGATE_TESTS} && can_use('Test::Simple', '0.88') && can_use('Test::Aggregate', '0.35_05')) {
grep { $_ ne 't/aggregate.t' }
map { glob } qw[t/*.t t/aggregate/*.t];
}
+ author_requires 'CatalystX::LeakChecker', '0.03'; # Skipped if this isn't installed
+ author_requires 'File::Copy::Recursive'; # For http server test
author_tests 't/author';
author_requires(map {; $_ => 0 } qw(
# NOTE - This is the version number of the _incompatible_ code,
# not the version number of the fixed version.
my %conflicts = (
+ 'Catalyst::Model::Akismet' => '0.02',
'Catalyst::Component::ACCEPT_CONTEXT' => '0.06',
'Catalyst::Plugin::ENV' => '9999', # This plugin is just stupid, full stop
# should have been a core fix.
# TAR on 10.4 wants COPY_EXTENDED_ATTRIBUTES_DISABLE
# On 10.5 (Leopard) it wants COPYFILE_DISABLE
- die("Oh, you got Snow Lepoard, snazzy. Please read the man page for tar to find out if Apple renamed COPYFILE_DISABLE again and fix this Makefile.PL please?\n") if $osx_ver =~ /^10.6/;
- my $attr = $osx_ver =~ /^10.5/ ? 'COPYFILE_DISABLE' : 'COPY_EXTENDED_ATTRIBUTES_DISABLE';
+ die("Oh, you got Ceiling Cat, snazzy. Please read the man page for tar or Google to find out if Apple renamed COPYFILE_DISABLE (it was COPY_EXTENDED_ATTRIBUTES_DISABLE originally) again and fix this Makefile.PL please?\n") if $osx_ver =~ /^10.7/;
+ my $attr = $osx_ver =~ /^10.(5|6)/ ? 'COPYFILE_DISABLE' : 'COPY_EXTENDED_ATTRIBUTES_DISABLE';
makemaker_args(dist => { PREOP => qq{\@if [ "\$\$$attr" != "true" ]; then}.
qq{ echo "You must set the ENV variable $attr to true,"; }.
# Remember to update this in Catalyst::Runtime as well!
- our $VERSION = '5.80011';
+ our $VERSION = '5.80013';
{
my $dev_version = $VERSION =~ /_\d{2}$/;
your code like this:
$c->forward('foo') || return;
+
+ Another note is that C<< $c->forward >> always returns a scalar because it
+ actually returns $c->state which operates in a scalar context.
+ Thus, something like:
+
+ return @array;
+
+ in an action that is forwarded to is going to return a scalar,
+ i.e. how many items are in that array, which is probably not what you want.
+ If you need to return an array then return a reference to it,
+ or stash it like so:
+
+ $c->stash->{array} = \@array;
+
+ and access it from the stash.
=cut
=head2 $c->go( $class, $method, [, \@captures, \@arguments ] )
- Almost the same as L<< detach|/"$c->detach( $action [, \@arguments ] )" >>, but does a full dispatch like L</visit>,
- instead of just calling the new C<$action> /
- C<< $class->$method >>. This means that C<begin>, C<auto> and the
- method you visit are called, just like a new request.
-
- C<< $c->stash >> is kept unchanged.
+ The relationship between C<go> and
+ L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >> is the same as
+ the relationship between
+ L<< forward|/"$c->forward( $class, $method, [, \@arguments ] )" >> and
+ L<< detach|/"$c->detach( $action [, \@arguments ] )" >>. Like C<< $c->visit >>,
+ C<< $c->go >> will perform a full dispatch on the specified action or method,
+ with localized C<< $c->action >> and C<< $c->namespace >>. Like C<detach>,
+ C<go> escapes the processing of the current request chain on completion, and
+ does not return to its caller.
=cut
=head2 $c->state
- Contains the return value of the last executed action.
+ Contains the return value of the last executed action.
+ Note that << $c->state >> operates in a scalar context which means that all
+ values it returns are scalar.
=head2 $c->clear_errors
# if we were given a regexp to search against, we're done.
return if ref $name;
+ # skip regexp fallback if configured
+ return
+ if $appclass->config->{disable_component_resolution_regex_fallback};
+
# regexp fallback
$query = qr/$name/i;
@result = grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
(join '", "', @result) . "'. Relying on regexp fallback behavior for " .
"component resolution is unreliable and unsafe.";
my $short = $result[0];
- $short =~ s/.*?Model:://;
+ # remove the component namespace prefix
+ $short =~ s/.*?(Model|Controller|View):://;
my $shortmess = Carp::shortmess('');
if ($shortmess =~ m#Catalyst/Plugin#) {
$msg .= " You probably need to set '$short' instead of '${name}' in this " .
$msg .= " You probably need to set '$short' instead of '${name}' in this " .
"component's config";
} else {
- $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}({'${name}'}), " .
+ $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}('${name}'), " .
"but if you really wanted to search, pass in a regexp as the argument " .
"like so: \$c->${warn_for}(qr/${name}/)";
}
If C<$name> is a regexp, a list of components matched against the full
component name will be returned.
+ If Catalyst can't find a component by name, it will fallback to regex
+ matching by default. To disable this behaviour set
+ disable_component_resolution_regex_fallback to a true value.
+
+ __PACKAGE__->config( disable_component_resolution_regex_fallback => 1 );
+
=cut
sub component {
my $name = $class->config->{name} || 'Application';
$class->log->info("$name powered by Catalyst $Catalyst::VERSION");
}
- $class->log->_flush() if $class->log->can('_flush');
# Make sure that the application class becomes immutable at this point,
B::Hooks::EndOfScope::on_scope_end {
. "Class::Accessor(::Fast)?\nPlease pass "
. "(replace_constructor => 1)\nwhen making your class immutable.\n";
}
- $meta->make_immutable(replace_constructor => 1)
- unless $meta->is_immutable;
+ $meta->make_immutable(
+ replace_constructor => 1,
+ ) unless $meta->is_immutable;
};
+ if ($class->config->{case_sensitive}) {
+ $class->log->warn($class . "->config->{case_sensitive} is set.");
+ $class->log->warn("This setting is deprecated and planned to be removed in Catalyst 5.81.");
+ }
+
$class->setup_finalize;
+ # Should be the last thing we do so that user things hooking
+ # setup_finalize can log..
+ $class->log->_flush() if $class->log->can('_flush');
+ return 1; # Explicit return true as people have __PACKAGE__->setup as the last thing in their class. HATE.
}
$class->setup_finished(1);
}
- =head2 $c->uri_for( $path, @args?, \%query_values? )
+ =head2 $c->uri_for( $path?, @args?, \%query_values? )
=head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
provided path, and the additional arguments and query parameters provided.
When used as a string, provides a textual URI.
+ If no arguments are provided, the URI for the current action is returned.
+ To return the current action and also provide @args, use
+ C<< $c->uri_for( $c->action, @args ) >>.
+
If the first argument is a string, it is taken as a public URI path relative
to C<< $c->namespace >> (if it doesn't begin with a forward slash) or
relative to the application root (if it does). It is then merged with
}
if ( blessed($path) ) { # action object
- my $captures = ( scalar @args && ref $args[0] eq 'ARRAY'
- ? shift(@args)
- : [] );
+ my $captures = [ map { s|/|%2F|; $_; }
+ ( scalar @args && ref $args[0] eq 'ARRAY'
+ ? @{ shift(@args) }
+ : ()) ];
my $action = $path;
$path = $c->dispatcher->uri_for_action($action, $captures);
if (not defined $path) {
carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
+ s|/|%2F| for @args;
unshift(@args, $path);
# is this a root-level call or a forwarded call?
if ( $callsub =~ /forward$/ ) {
+ my $parent = $c->stack->[-1];
# forward, locate the caller
- if ( my $parent = $c->stack->[-1] ) {
+ if ( exists $c->counter->{"$parent"} ) {
$c->stats->profile(
begin => $action,
parent => "$parent" . $c->counter->{"$parent"},
sub version { return $Catalyst::VERSION }
+ =head1 CONFIGURATION
+
+ There are a number of 'base' config variables which can be set:
+
+ =over
+
+ =item *
+
+ C<default_model> - The default model picked if you say C<< $c->model >>. See L</$c->model($name)>.
+
+ =item *
+
+ C<default_view> - The default view to be rendered or returned when C<< $c->view >>. See L</$c->view($name)>.
+ is called.
+
+ =item *
+
+ C<disable_component_resolution_regex_fallback> - Turns
+ off the deprecated component resolution functionality so
+ that if any of the component methods (e.g. C<< $c->controller('Foo') >>)
+ are called then regex search will not be attempted on string values and
+ instead C<undef> will be returned.
+
+ =item *
+
+ C<home> - The application home directory. In an uninstalled application,
+ this is the top level application directory. In an installed application,
+ this will be the directory containing C<< MyApp.pm >>.
+
+ =item *
+
+ C<ignore_frontend_proxy> - See L</PROXY SUPPORT>
+
+ =item *
+
+ C<name> - The name of the application in debug messages and the debug and
+ welcome screens
+
+ =item *
+
+ C<parse_on_demand> - The request body (for example file uploads) will not be parsed
+ until it is accessed. This allows you to (for example) check authentication (and reject
+ the upload) before actually recieving all the data. See L</ON-DEMAND PARSER>
+
+ =item *
+
+ C<root> - The root directory for templates. Usually this is just a
+ subdirectory of the home directory, but you can set it to change the
+ templates to a different directory.
+
+ =item *
+
+ C<search_extra> - Array reference passed to Module::Pluggable to for additional
+ namespaces from which components will be loaded (and constructed and stored in
+ C<< $c->components >>).
+
+ =item *
+
+ C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >>
+ to be shown in hit debug tables in the test server.
+
+ =item *
+
+ C<using_frontend_proxy> - See L</PROXY SUPPORT>.
+
+ =back
+
=head1 INTERNAL ACTIONS
Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
MyApp->config(show_internal_actions => 1);
- =head1 CASE SENSITIVITY
-
- By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
- mapped to C</foo/bar>. You can activate case sensitivity with a config
- parameter.
-
- MyApp->config(case_sensitive => 1);
-
- This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
-
=head1 ON-DEMAND PARSER
The request body is usually parsed at the beginning of a request,
acme: Leon Brocard <leon@astray.com>
+ abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
+
Andrew Bramble
Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
David E. Wheeler
+dhoss: Devin Austin <dhoss@cpan.org>
+
dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
Drew Taylor
Geoff Richards
+ groditi: Guillermo Roditi <groditi@gmail.com>
+
hobbs: Andrew Rodland <andrew@cleverdomain.org>
ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>