4 use Moose::Meta::Class ();
5 extends 'Catalyst::Component';
6 use Moose::Util qw/find_meta/;
8 use B::Hooks::EndOfScope ();
10 use Catalyst::Exception;
11 use Catalyst::Exception::Detach;
12 use Catalyst::Exception::Go;
14 use Catalyst::Request;
15 use Catalyst::Request::Upload;
16 use Catalyst::Response;
18 use Catalyst::Controller;
19 use Devel::InnerPackage ();
21 use Module::Pluggable::Object ();
22 use Text::SimpleTable ();
23 use Path::Class::Dir ();
24 use Path::Class::File ();
28 use Tree::Simple qw/use_weak_refs/;
29 use Tree::Simple::Visitor::FindByUID;
30 use Class::C3::Adopt::NEXT;
31 use List::MoreUtils qw/uniq/;
34 use Carp qw/croak carp shortmess/;
36 BEGIN { require 5.008004; }
38 #I imagine that very few of these really need to be class variables. if any.
39 #maybe we should just make them attributes with a default?
40 __PACKAGE__->mk_classdata($_)
41 for qw/components arguments dispatcher engine log dispatcher_class
42 engine_class context_class request_class response_class stats_class
45 __PACKAGE__->context_class('Catalyst::Context');
46 __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
47 __PACKAGE__->engine_class('Catalyst::Engine::CGI');
48 __PACKAGE__->request_class('Catalyst::Request');
49 __PACKAGE__->response_class('Catalyst::Response');
50 __PACKAGE__->stats_class('Catalyst::Stats');
52 # Remember to update this in Catalyst::Runtime as well!
54 our $VERSION = '5.80013';
57 my $dev_version = $VERSION =~ /_\d{2}$/;
58 *_IS_DEVELOPMENT_VERSION = sub () { $dev_version };
61 $VERSION = eval $VERSION;
67 my ( $class, @arguments ) = @_;
69 # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
71 return unless $class eq 'Catalyst';
73 my $caller = caller();
74 return if $caller eq 'main';
76 # Kill Adopt::NEXT warnings if we're a non-RC version
77 unless (_IS_DEVELOPMENT_VERSION()) {
78 Class::C3::Adopt::NEXT->unimport(qr/^Catalyst::/);
81 my $meta = Moose::Meta::Class->initialize($caller);
82 unless ( $caller->isa('Catalyst') ) {
83 my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
84 $meta->superclasses(@superclasses);
86 # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp
87 $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses);
89 unless( $meta->has_method('meta') ){
90 $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
93 $caller->arguments( [@arguments] );
97 sub _application { $_[0] }
101 Catalyst - The Elegant MVC Web Application Framework
105 See the L<Catalyst::Manual> distribution for comprehensive
106 documentation and tutorials.
108 # Install Catalyst::Devel for helpers and other development tools
109 # use the helper to create a new application
112 # add models, views, controllers
113 script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
114 script/myapp_create.pl view MyTemplate TT
115 script/myapp_create.pl controller Search
117 # built in testserver -- use -r to restart automatically on changes
118 # --help to see all available options
119 script/myapp_server.pl
121 # command line testing interface
122 script/myapp_test.pl /yada
125 use Catalyst qw/-Debug/; # include plugins here as well
127 ### In lib/MyApp/Controller/Root.pm (autocreated)
128 sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
129 my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
130 $c->stash->{template} = 'foo.tt'; # set the template
131 # lookup something from db -- stash vars are passed to TT
133 $c->model('Database::Foo')->search( { country => $args[0] } );
134 if ( $c->req->params->{bar} ) { # access GET or POST parameters
135 $c->forward( 'bar' ); # process another action
136 # do something else after forward returns
140 # The foo.tt TT template can use the stash data from the database
141 [% WHILE (item = data.next) %]
145 # called for /bar/of/soap, /bar/of/soap/10, etc.
146 sub bar : Path('/bar/of/soap') { ... }
148 # called for all actions, from the top-most controller downwards
150 my ( $self, $c ) = @_;
151 if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
152 $c->res->redirect( '/login' ); # require login
153 return 0; # abort request and go immediately to end()
155 return 1; # success; carry on to next action
158 # called after all actions are finished
160 my ( $self, $c ) = @_;
161 if ( scalar @{ $c->error } ) { ... } # handle errors
162 return if $c->res->body; # already have a response
163 $c->forward( 'MyApp::View::TT' ); # render template
166 ### in MyApp/Controller/Foo.pm
167 # called for /foo/bar
168 sub bar : Local { ... }
170 # called for /blargle
171 sub blargle : Global { ... }
173 # an index action matches /foo, but not /foo/1, etc.
174 sub index : Private { ... }
176 ### in MyApp/Controller/Foo/Bar.pm
177 # called for /foo/bar/baz
178 sub baz : Local { ... }
180 # first Root auto is called, then Foo auto, then this
181 sub auto : Private { ... }
183 # powerful regular expression paths are also possible
184 sub details : Regex('^product/(\w+)/details$') {
185 my ( $self, $c ) = @_;
186 # extract the (\w+) from the URI
187 my $product = $c->req->captures->[0];
190 See L<Catalyst::Manual::Intro> for additional information.
194 Catalyst is a modern framework for making web applications without the
195 pain usually associated with this process. This document is a reference
196 to the main Catalyst application. If you are a new user, we suggest you
197 start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
199 See L<Catalyst::Manual> for more documentation.
201 Catalyst plugins can be loaded by naming them as arguments to the "use
202 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
203 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
206 use Catalyst qw/My::Module/;
208 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
209 fully qualify the name by using a unary plus:
213 +Fully::Qualified::Plugin::Name
216 Special flags like C<-Debug> and C<-Engine> can also be specified as
217 arguments when Catalyst is loaded:
219 use Catalyst qw/-Debug My::Module/;
221 The position of plugins and flags in the chain is important, because
222 they are loaded in the order in which they appear.
224 The following flags are supported:
228 Enables debug output. You can also force this setting from the system
229 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
230 settings override the application, with <MYAPP>_DEBUG having the highest
235 Forces Catalyst to use a specific engine. Omit the
236 C<Catalyst::Engine::> prefix of the engine name, i.e.:
238 use Catalyst qw/-Engine=CGI/;
242 Forces Catalyst to use a specific home directory, e.g.:
244 use Catalyst qw[-Home=/usr/mst];
246 This can also be done in the shell environment by setting either the
247 C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
248 is replaced with the uppercased name of your application, any "::" in
249 the name will be replaced with underscores, e.g. MyApp::Web should use
250 MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
254 use Catalyst '-Log=warn,fatal,error';
256 Specifies a comma-delimited list of log levels.
260 Enables statistics collection and reporting. You can also force this setting
261 from the system environment with CATALYST_STATS or <MYAPP>_STATS. The
262 environment settings override the application, with <MYAPP>_STATS having the
267 use Catalyst qw/-Stats=1/
273 sub _comp_search_prefixes {
275 return map $c->components->{ $_ }, $c->_comp_names_search_prefixes(@_);
278 # search components given a name and some prefixes
279 sub _comp_names_search_prefixes {
280 my ( $c, $name, @prefixes ) = @_;
281 my $appclass = ref $c || $c;
282 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
283 $filter = qr/$filter/; # Compile regex now rather than once per loop
285 # map the original component name to the sub part that we will search against
286 my %eligible = map { my $n = $_; $n =~ s{^$appclass\::[^:]+::}{}; $_ => $n; }
287 grep { /$filter/ } keys %{ $c->components };
289 # undef for a name will return all
290 return keys %eligible if !defined $name;
292 my $query = ref $name ? $name : qr/^$name$/i;
293 my @result = grep { $eligible{$_} =~ m{$query} } keys %eligible;
295 return @result if @result;
297 # if we were given a regexp to search against, we're done.
300 # skip regexp fallback if configured
302 if $appclass->config->{disable_component_resolution_regex_fallback};
306 @result = grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
308 # no results? try against full names
310 @result = grep { m{$query} } keys %eligible;
313 # don't warn if we didn't find any results, it just might not exist
315 # Disgusting hack to work out correct method name
316 my $warn_for = lc $prefixes[0];
317 my $msg = "Used regexp fallback for \$c->${warn_for}('${name}'), which found '" .
318 (join '", "', @result) . "'. Relying on regexp fallback behavior for " .
319 "component resolution is unreliable and unsafe.";
320 my $short = $result[0];
321 # remove the component namespace prefix
322 $short =~ s/.*?(Model|Controller|View):://;
323 my $shortmess = Carp::shortmess('');
324 if ($shortmess =~ m#Catalyst/Plugin#) {
325 $msg .= " You probably need to set '$short' instead of '${name}' in this " .
327 } elsif ($shortmess =~ m#Catalyst/lib/(View|Controller)#) {
328 $msg .= " You probably need to set '$short' instead of '${name}' in this " .
329 "component's config";
331 $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}('${name}'), " .
332 "but if you really wanted to search, pass in a regexp as the argument " .
333 "like so: \$c->${warn_for}(qr/${name}/)";
335 $c->log->warn( "${msg}$shortmess" );
341 # Find possible names for a prefix
343 my ( $c, @prefixes ) = @_;
344 my $appclass = ref $c || $c;
346 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
348 my @names = map { s{$filter}{}; $_; }
349 $c->_comp_names_search_prefixes( undef, @prefixes );
354 # Filter a component before returning by calling ACCEPT_CONTEXT if available
355 sub _filter_component {
356 my ( $c, $comp, @args ) = @_;
358 if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) {
359 return $comp->ACCEPT_CONTEXT( $c, @args );
365 =head2 COMPONENT ACCESSORS
367 =head2 $c->controllers
369 Returns the available names which can be passed to $c->controller
375 return $c->_comp_names(qw/Controller C/);
380 Returns the available names which can be passed to $c->model
386 return $c->_comp_names(qw/Model M/);
392 Returns the available names which can be passed to $c->view
398 return $c->_comp_names(qw/View V/);
401 =head2 $c->comp($name)
403 =head2 $c->component($name)
405 Gets a component object by name. This method is not recommended,
406 unless you want to get a specific component by full
407 class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >>
408 should be used instead.
410 If C<$name> is a regexp, a list of components matched against the full
411 component name will be returned.
413 If Catalyst can't find a component by name, it will fallback to regex
414 matching by default. To disable this behaviour set
415 disable_component_resolution_regex_fallback to a true value.
417 __PACKAGE__->config( disable_component_resolution_regex_fallback => 1 );
422 my ( $c, $name, @args ) = @_;
425 my $comps = $c->components;
428 # is it the exact name?
429 return $c->_filter_component( $comps->{ $name }, @args )
430 if exists $comps->{ $name };
432 # perhaps we just omitted "MyApp"?
433 my $composed = ( ref $c || $c ) . "::${name}";
434 return $c->_filter_component( $comps->{ $composed }, @args )
435 if exists $comps->{ $composed };
437 # search all of the models, views and controllers
438 my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ );
439 return $c->_filter_component( $comp, @args ) if $comp;
442 # This is here so $c->comp( '::M::' ) works
443 my $query = ref $name ? $name : qr{$name}i;
445 my @result = grep { m{$query} } keys %{ $c->components };
446 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
449 $c->log->warn( Carp::shortmess(qq(Found results for "${name}" using regexp fallback)) );
450 $c->log->warn( 'Relying on the regexp fallback behavior for component resolution' );
451 $c->log->warn( 'is unreliable and unsafe. You have been warned' );
452 return $c->_filter_component( $result[ 0 ], @args );
455 # I would expect to return an empty list here, but that breaks back-compat
459 return sort keys %{ $c->components };
462 =head2 CLASS DATA AND HELPER CLASSES
466 Returns or takes a hashref containing the application's configuration.
468 __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
470 You can also use a C<YAML>, C<XML> or L<Config::General> config file
471 like C<myapp.conf> in your applications home directory. See
472 L<Catalyst::Plugin::ConfigLoader>.
474 =head3 Cascading configuration
476 The config method is present on all Catalyst components, and configuration
477 will be merged when an application is started. Configuration loaded with
478 L<Catalyst::Plugin::ConfigLoader> takes precedence over other configuration,
479 followed by configuration in your top level C<MyApp> class. These two
480 configurations are merged, and then configuration data whose hash key matches a
481 component name is merged with configuration for that component.
483 The configuration for a component is then passed to the C<new> method when a
484 component is constructed.
488 MyApp->config({ 'Model::Foo' => { bar => 'baz', overrides => 'me' } });
489 MyApp::Model::Foo->config({ quux => 'frob', 'overrides => 'this' });
491 will mean that C<MyApp::Model::Foo> receives the following data when
494 MyApp::Model::Foo->new({
502 around config => sub {
506 croak('Setting config after setup has been run is not allowed.')
507 if ( @_ and $c->setup_finished );
514 Returns the logging object instance. Unless it is already set, Catalyst
515 sets this up with a L<Catalyst::Log> object. To use your own log class,
516 set the logger with the C<< __PACKAGE__->log >> method prior to calling
517 C<< __PACKAGE__->setup >>.
519 __PACKAGE__->log( MyLogger->new );
524 $c->log->info( 'Now logging with my own logger!' );
526 Your log class should implement the methods described in
532 Returns 1 if debug mode is enabled, 0 otherwise.
534 You can enable debug mode in several ways:
538 =item By calling myapp_server.pl with the -d flag
540 =item With the environment variables MYAPP_DEBUG, or CATALYST_DEBUG
542 =item The -Debug option in your MyApp.pm
544 =item By declaring C<sub debug { 1 }> in your MyApp.pm.
548 Calling C<< $c->debug(1) >> has no effect.
554 =head2 $c->dispatcher
556 Returns the dispatcher instance. See L<Catalyst::Dispatcher>.
560 Returns the engine instance. See L<Catalyst::Engine>.
563 =head2 UTILITY METHODS
565 =head2 $c->path_to(@path)
567 Merges C<@path> with C<< $c->config->{home} >> and returns a
568 L<Path::Class::Dir> object. Note you can usually use this object as
569 a filename, but sometimes you will have to explicitly stringify it
570 yourself by calling the C<< ->stringify >> method.
574 $c->path_to( 'db', 'sqlite.db' );
579 my ( $c, @path ) = @_;
580 my $path = Path::Class::Dir->new( $c->config->{home}, @path );
581 if ( -d $path ) { return $path }
582 else { return Path::Class::File->new( $c->config->{home}, @path ) }
585 =head2 $c->plugin( $name, $class, @args )
587 Helper method for plugins. It creates a class data accessor/mutator and
588 loads and instantiates the given class.
590 MyApp->plugin( 'prototype', 'HTML::Prototype' );
592 $c->prototype->define_javascript_functions;
594 B<Note:> This method of adding plugins is deprecated. The ability
595 to add plugins like this B<will be removed> in a Catalyst 5.81.
596 Please do not use this functionality in new code.
601 my ( $class, $name, $plugin, @args ) = @_;
603 # See block comment in t/unit_core_plugin.t
604 $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in Catalyst 5.81/);
606 $class->_register_plugin( $plugin, 1 );
608 eval { $plugin->import };
609 $class->mk_classdata($name);
611 eval { $obj = $plugin->new(@args) };
614 Catalyst::Exception->throw( message =>
615 qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
619 $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
625 Initializes the dispatcher and engine, loads any plugins, and loads the
626 model, view, and controller components. You may also specify an array
627 of plugins to load here, if you choose to not load them in the C<use
631 MyApp->setup( qw/-Debug/ );
636 my ( $class, @arguments ) = @_;
637 croak('Running setup more than once')
638 if ( $class->setup_finished );
640 unless ( $class->isa('Catalyst') ) {
642 Catalyst::Exception->throw(
643 message => qq/'$class' does not inherit from Catalyst/ );
646 if ( $class->arguments ) {
647 @arguments = ( @arguments, @{ $class->arguments } );
653 foreach (@arguments) {
657 ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
659 elsif (/^-(\w+)=?(.*)$/) {
660 $flags->{ lc $1 } = $2;
663 push @{ $flags->{plugins} }, $_;
667 $class->setup_home( delete $flags->{home} );
669 $class->setup_log( delete $flags->{log} );
670 $class->setup_plugins( delete $flags->{plugins} );
671 $class->setup_dispatcher( delete $flags->{dispatcher} );
672 $class->setup_engine( delete $flags->{engine} );
673 $class->setup_stats( delete $flags->{stats} );
675 for my $flag ( sort keys %{$flags} ) {
677 if ( my $code = $class->can( 'setup_' . $flag ) ) {
678 &$code( $class, delete $flags->{$flag} );
681 $class->log->warn(qq/Unknown flag "$flag"/);
685 eval { require Catalyst::Devel; };
686 if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
687 $class->log->warn(<<"EOF");
688 You are running an old script!
690 Please update by running (this will overwrite existing files):
691 catalyst.pl -force -scripts $class
693 or (this will not overwrite existing files):
694 catalyst.pl -scripts $class
699 if ( $class->debug ) {
700 my @plugins = map { "$_ " . ( $_->VERSION || '' ) } $class->registered_plugins;
703 my $column_width = Catalyst::Utils::term_width() - 6;
704 my $t = Text::SimpleTable->new($column_width);
705 $t->row($_) for @plugins;
706 $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
709 my $dispatcher = $class->dispatcher;
710 my $engine = $class->engine;
711 my $home = $class->config->{home};
713 $class->log->debug(sprintf(q/Loaded dispatcher "%s"/, blessed($dispatcher)));
714 $class->log->debug(sprintf(q/Loaded engine "%s"/, blessed($engine)));
718 ? $class->log->debug(qq/Found home "$home"/)
719 : $class->log->debug(qq/Home "$home" doesn't exist/)
720 : $class->log->debug(q/Couldn't find home/);
723 # Call plugins setup, this is stupid and evil.
724 # Also screws C3 badly on 5.10, hack to avoid.
726 no warnings qw/redefine/;
727 local *setup = sub { };
728 $class->setup unless $Catalyst::__AM_RESTARTING;
731 # Initialize our data structure
732 $class->components( {} );
734 $class->setup_components;
736 if ( $class->debug ) {
737 my $column_width = Catalyst::Utils::term_width() - 8 - 9;
738 my $t = Text::SimpleTable->new( [ $column_width, 'Class' ], [ 8, 'Type' ] );
739 for my $comp ( sort keys %{ $class->components } ) {
740 my $type = ref $class->components->{$comp} ? 'instance' : 'class';
741 $t->row( $comp, $type );
743 $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
744 if ( keys %{ $class->components } );
747 # Add our self to components, since we are also a component
748 if( $class->isa('Catalyst::Controller') ){
749 $class->components->{$class} = $class;
752 $class->setup_actions;
754 if ( $class->debug ) {
755 my $name = $class->config->{name} || 'Application';
756 $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
758 $class->log->_flush() if $class->log->can('_flush');
760 # Make sure that the application class becomes immutable at this point,
761 B::Hooks::EndOfScope::on_scope_end {
763 my $meta = Class::MOP::get_metaclass_by_name($class);
766 && ! { $meta->immutable_options }->{replace_constructor}
768 $class->isa('Class::Accessor::Fast')
769 || $class->isa('Class::Accessor')
772 warn "You made your application class ($class) immutable, "
773 . "but did not inline the\nconstructor. "
774 . "This will break catalyst, as your app \@ISA "
775 . "Class::Accessor(::Fast)?\nPlease pass "
776 . "(replace_constructor => 1)\nwhen making your class immutable.\n";
778 $meta->make_immutable(
779 replace_constructor => 1,
780 ) unless $meta->is_immutable;
783 $class->setup_finalize;
787 =head2 $app->setup_finalize
789 A hook to attach modifiers to.
790 Using C<< after setup => sub{}; >> doesn't work, because of quirky things done for plugin setup.
791 Also better than C< setup_finished(); >, as that is a getter method.
797 ## do stuff, i.e., determine a primary key column for sessions stored in a DB
799 $app->next::method(@_);
808 $class->setup_finished(1);
811 =head2 $c->uri_for( $path, @args?, \%query_values? )
813 =head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
815 Constructs an absolute L<URI> object based on the application root, the
816 provided path, and the additional arguments and query parameters provided.
817 When used as a string, provides a textual URI.
819 If the first argument is a string, it is taken as a public URI path relative
820 to C<< $c->namespace >> (if it doesn't begin with a forward slash) or
821 relative to the application root (if it does). It is then merged with
822 C<< $c->request->base >>; any C<@args> are appended as additional path
823 components; and any C<%query_values> are appended as C<?foo=bar> parameters.
825 If the first argument is a L<Catalyst::Action> it represents an action which
826 will have its path resolved using C<< $c->dispatcher->uri_for_action >>. The
827 optional C<\@captures> argument (an arrayref) allows passing the captured
828 variables that are needed to fill in the paths of Chained and Regex actions;
829 once the path is resolved, C<uri_for> continues as though a path was
830 provided, appending any arguments or parameters and creating an absolute
833 The captures for the current request can be found in
834 C<< $c->request->captures >>, and actions can be resolved using
835 C<< Catalyst::Controller->action_for($name) >>. If you have a private action
836 path, use C<< $c->uri_for_action >> instead.
838 # Equivalent to $c->req->uri
839 $c->uri_for($c->action, $c->req->captures,
840 @{ $c->req->args }, $c->req->params);
842 # For the Foo action in the Bar controller
843 $c->uri_for($c->controller('Bar')->action_for('Foo'));
845 # Path to a static resource
846 $c->uri_for('/static/images/logo.png');
850 =head2 $c->welcome_message
852 Returns the Catalyst welcome HTML page.
856 sub welcome_message {
858 my $name = $c->config->{name};
859 my $logo = $c->uri_for('/static/images/catalyst_logo.png');
860 my $prefix = Catalyst::Utils::appprefix( ref $c );
861 $c->response->content_type('text/html; charset=utf-8');
863 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
864 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
865 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
867 <meta http-equiv="Content-Language" content="en" />
868 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
869 <title>$name on Catalyst $VERSION</title>
870 <style type="text/css">
873 background-color: #eee;
882 background-color: #ccc;
883 border: 1px solid #aaa;
888 font-family: verdana, tahoma, sans-serif;
891 font-family: verdana, tahoma, sans-serif;
894 text-decoration: none;
896 border-bottom: 1px dotted #bbb;
898 :link:hover, :visited:hover {
911 background-color: #fff;
912 border: 1px solid #aaa;
938 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
943 <img src="$logo" alt="Catalyst Logo" />
945 <p>Welcome to the world of Catalyst.
946 This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
947 framework will make web development something you had
948 never expected it to be: Fun, rewarding, and quick.</p>
949 <h2>What to do now?</h2>
950 <p>That really depends on what <b>you</b> want to do.
951 We do, however, provide you with a few starting points.</p>
952 <p>If you want to jump right into web development with Catalyst
953 you might want to start with a tutorial.</p>
954 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
956 <p>Afterwards you can go on to check out a more complete look at our features.</p>
958 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
959 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
961 <h2>What to do next?</h2>
962 <p>Next it's time to write an actual application. Use the
963 helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&mode=all">controllers</a>,
964 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&mode=all">models</a>, and
965 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&mode=all">views</a>;
966 they can save you a lot of work.</p>
967 <pre><code>script/${prefix}_create.pl -help</code></pre>
968 <p>Also, be sure to check out the vast and growing
969 collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
970 you are likely to find what you need there.
974 <p>Catalyst has a very active community. Here are the main places to
975 get in touch with us.</p>
978 <a href="http://dev.catalyst.perl.org">Wiki</a>
981 <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a>
984 <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
987 <h2>In conclusion</h2>
988 <p>The Catalyst team hopes you will enjoy using Catalyst as much
989 as we enjoyed making it. Please contact us if you have ideas
990 for improvement or other feedback.</p>
998 =head1 INTERNAL METHODS
1000 These methods are not meant to be used by end users.
1002 =head2 $c->components
1004 Returns a hash of components.
1006 =head2 $c->context_class
1008 Returns or sets the context class.
1010 =head2 $c->dispatcher_class
1012 Returns or sets the dispatcher class.
1014 =head2 $c->engine_class
1016 Returns or sets the engine class.
1020 =head2 $c->prepare( @arguments )
1022 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1028 my ( $class, @arguments ) = @_;
1031 # After the app/ctxt split, this should become an attribute based on something passed
1032 # into the application.
1033 $class->context_class( ref $class || $class ) unless $class->context_class;
1035 my $app = $class->new({});
1036 my $c = $class->context_class->new( application => $app );
1038 # For on-demand data
1039 $c->request->_context($c);
1040 $c->response->_context($c);
1042 #surely this is not the most efficient way to do things...
1043 $c->stats($class->stats_class->new)->enable($c->use_stats);
1045 $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
1048 #XXX reuse coderef from can
1049 # Allow engine to direct the prepare flow (for POE)
1050 if ( $c->engine->can('prepare') ) {
1051 $c->engine->prepare( $c, @arguments );
1054 $c->prepare_request(@arguments);
1055 $c->prepare_connection;
1056 $c->prepare_query_parameters;
1057 $c->prepare_headers;
1058 $c->prepare_cookies;
1061 # Prepare the body for reading, either by prepare_body
1062 # or the user, if they are using $c->read
1065 # Parse the body unless the user wants it on-demand
1066 unless ( $c->config->{parse_on_demand} ) {
1071 my $method = $c->req->method || '';
1072 my $path = $c->req->path;
1073 $path = '/' unless length $path;
1074 my $address = $c->req->address || '';
1076 $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1084 =head2 $c->handle_request( $class, @arguments )
1086 Called to handle each HTTP request.
1090 sub handle_request {
1091 my ( $class, @arguments ) = @_;
1093 # Always expect worst case!
1096 if ($class->debug) {
1097 my $secs = time - $START || 1;
1098 my $av = sprintf '%.3f', $COUNT / $secs;
1099 my $time = localtime time;
1100 $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1103 my $c = $class->prepare(@arguments);
1105 $status = $c->finalize;
1108 if ( my $error = $@ ) {
1110 $class->log->error(qq/Caught exception in engine "$error"/);
1115 if(my $coderef = $class->log->can('_flush')){
1116 $class->log->$coderef();
1122 =head2 $c->request_class
1124 Returns or sets the request class.
1126 =head2 $c->response_class
1128 Returns or sets the response class.
1136 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1138 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1140 Sets an action in a given namespace.
1144 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1146 =head2 $c->setup_actions($component)
1148 Sets up actions for a component.
1152 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1154 =head2 $c->setup_components
1156 This method is called internally to set up the application's components.
1158 It finds modules by calling the L<locate_components> method, expands them to
1159 package names with the L<expand_component_module> method, and then installs
1160 each component into the application.
1162 The C<setup_components> config option is passed to both of the above methods.
1164 Installation of each component is performed by the L<setup_component> method,
1169 sub setup_components {
1172 my $config = $class->config->{ setup_components };
1174 my @comps = sort { length $a <=> length $b }
1175 $class->locate_components($config);
1176 my %comps = map { $_ => 1 } @comps;
1178 my $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @comps;
1179 $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
1180 qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
1181 ) if $deprecatedcatalyst_component_names;
1183 for my $component ( @comps ) {
1185 # We pass ignore_loaded here so that overlay files for (e.g.)
1186 # Model::DBI::Schema sub-classes are loaded - if it's in @comps
1187 # we know M::P::O found a file on disk so this is safe
1189 Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
1191 # Needs to be done as soon as the component is loaded, as loading a sub-component
1192 # (next time round the loop) can cause us to get the wrong metaclass..
1193 $class->_controller_init_base_classes($component);
1196 for my $component (@comps) {
1197 $class->components->{ $component } = $class->setup_component($component);
1198 for my $component ($class->expand_component_module( $component, $config )) {
1199 next if $comps{$component};
1200 $class->_controller_init_base_classes($component); # Also cover inner packages
1201 $class->components->{ $component } = $class->setup_component($component);
1206 =head2 $c->locate_components( $setup_component_config )
1208 This method is meant to provide a list of component modules that should be
1209 setup for the application. By default, it will use L<Module::Pluggable>.
1211 Specify a C<setup_components> config option to pass additional options directly
1212 to L<Module::Pluggable>. To add additional search paths, specify a key named
1213 C<search_extra> as an array reference. Items in the array beginning with C<::>
1214 will have the application class name prepended to them.
1218 sub locate_components {
1222 my @paths = qw( ::Controller ::C ::Model ::M ::View ::V );
1223 my $extra = delete $config->{ search_extra } || [];
1225 push @paths, @$extra;
1227 my $locator = Module::Pluggable::Object->new(
1228 search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
1232 my @comps = $locator->plugins;
1237 =head2 $c->expand_component_module( $component, $setup_component_config )
1239 Components found by C<locate_components> will be passed to this method, which
1240 is expected to return a list of component (package) names to be set up.
1244 sub expand_component_module {
1245 my ($class, $module) = @_;
1246 return Devel::InnerPackage::list_packages( $module );
1249 =head2 $c->setup_component
1253 # FIXME - Ugly, ugly hack to ensure the we force initialize non-moose base classes
1254 # nearest to Catalyst::Controller first, no matter what order stuff happens
1255 # to be loaded. There are TODO tests in Moose for this, see
1256 # f2391d17574eff81d911b97be15ea51080500003
1257 sub _controller_init_base_classes {
1258 my ($app_class, $component) = @_;
1259 return unless $component->isa('Catalyst::Controller');
1260 foreach my $class ( reverse @{ mro::get_linear_isa($component) } ) {
1261 Moose::Meta::Class->initialize( $class )
1262 unless find_meta($class);
1266 sub setup_component {
1267 my( $class, $component ) = @_;
1269 unless ( $component->can( 'COMPONENT' ) ) {
1273 my $suffix = Catalyst::Utils::class2classsuffix( $component );
1274 my $config = $class->config->{ $suffix } || {};
1275 # Stash catalyst_component_name in the config here, so that custom COMPONENT
1276 # methods also pass it. local to avoid pointlessly shitting in config
1277 # for the debug screen, as $component is already the key name.
1278 local $config->{catalyst_component_name} = $component;
1280 my $instance = eval { $component->COMPONENT( $class, $config ); };
1282 if ( my $error = $@ ) {
1284 Catalyst::Exception->throw(
1285 message => qq/Couldn't instantiate component "$component", "$error"/
1289 unless (blessed $instance) {
1290 my $metaclass = Moose::Util::find_meta($component);
1291 my $method_meta = $metaclass->find_method_by_name('COMPONENT');
1292 my $component_method_from = $method_meta->associated_metaclass->name;
1293 my $value = defined($instance) ? $instance : 'undef';
1294 Catalyst::Exception->throw(
1296 qq/Couldn't instantiate component "$component", COMPONENT() method (from $component_method_from) didn't return an object-like value (value was $value)./
1302 =head2 $c->setup_dispatcher
1308 sub setup_dispatcher {
1309 my ( $class, $dispatcher ) = @_;
1312 $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
1315 if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
1316 $dispatcher = 'Catalyst::Dispatcher::' . $env;
1319 unless ($dispatcher) {
1320 $dispatcher = $class->dispatcher_class;
1323 Class::MOP::load_class($dispatcher);
1325 # dispatcher instance
1326 $class->dispatcher( $dispatcher->new );
1329 =head2 $c->setup_engine
1336 my ( $class, $engine ) = @_;
1339 $engine = 'Catalyst::Engine::' . $engine;
1342 if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
1343 $engine = 'Catalyst::Engine::' . $env;
1346 if ( $ENV{MOD_PERL} ) {
1347 my $meta = Class::MOP::get_metaclass_by_name($class);
1349 # create the apache method
1350 $meta->add_method('apache' => sub { shift->engine->apache });
1352 my ( $software, $version ) =
1353 $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
1356 $version =~ s/(\.[^.]+)\./$1/g;
1358 if ( $software eq 'mod_perl' ) {
1362 if ( $version >= 1.99922 ) {
1363 $engine = 'Catalyst::Engine::Apache2::MP20';
1366 elsif ( $version >= 1.9901 ) {
1367 $engine = 'Catalyst::Engine::Apache2::MP19';
1370 elsif ( $version >= 1.24 ) {
1371 $engine = 'Catalyst::Engine::Apache::MP13';
1375 Catalyst::Exception->throw( message =>
1376 qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
1381 # install the correct mod_perl handler
1382 if ( $version >= 1.9901 ) {
1383 *handler = sub : method {
1384 shift->handle_request(@_);
1388 *handler = sub ($$) { shift->handle_request(@_) };
1393 elsif ( $software eq 'Zeus-Perl' ) {
1394 $engine = 'Catalyst::Engine::Zeus';
1398 Catalyst::Exception->throw(
1399 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
1404 $engine = $class->engine_class;
1407 Class::MOP::load_class($engine);
1409 # check for old engines that are no longer compatible
1411 if ( $engine->isa('Catalyst::Engine::Apache')
1412 && !Catalyst::Engine::Apache->VERSION )
1417 elsif ( $engine->isa('Catalyst::Engine::Server::Base')
1418 && Catalyst::Engine::Server->VERSION le '0.02' )
1423 elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
1424 && $engine->VERSION eq '0.01' )
1429 elsif ($engine->isa('Catalyst::Engine::Zeus')
1430 && $engine->VERSION eq '0.01' )
1436 Catalyst::Exception->throw( message =>
1437 qq/Engine "$engine" is not supported by this version of Catalyst/
1442 $class->engine( $engine->new );
1445 =head2 $c->setup_home
1447 Sets up the home directory.
1452 my ( $class, $home ) = @_;
1454 if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
1458 $home ||= Catalyst::Utils::home($class);
1461 #I remember recently being scolded for assigning config values like this
1462 $class->config->{home} ||= $home;
1463 $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
1467 =head2 $c->setup_log
1469 Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and
1470 passing it to C<log()>. Pass in a comma-delimited list of levels to set the
1473 This method also installs a C<debug> method that returns a true value into the
1474 catalyst subclass if the "debug" level is passed in the comma-delimited list,
1475 or if the C<$CATALYST_DEBUG> environment variable is set to a true value.
1477 Note that if the log has already been setup, by either a previous call to
1478 C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>,
1479 that this method won't actually set up the log object.
1484 my ( $class, $levels ) = @_;
1487 $levels =~ s/^\s+//;
1488 $levels =~ s/\s+$//;
1489 my %levels = map { $_ => 1 } split /\s*,\s*/, $levels;
1491 my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
1492 if ( defined $env_debug ) {
1493 $levels{debug} = 1 if $env_debug; # Ugly!
1494 delete($levels{debug}) unless $env_debug;
1497 unless ( $class->log ) {
1498 $class->log( Catalyst::Log->new(keys %levels) );
1501 if ( $levels{debug} ) {
1502 Class::MOP::get_metaclass_by_name($class)->add_method('debug' => sub { 1 });
1503 $class->log->debug('Debug messages enabled');
1507 =head2 $c->setup_plugins
1513 =head2 $c->setup_stats
1515 Sets up timing statistics class.
1520 my ( $class, $stats ) = @_;
1522 Catalyst::Utils::ensure_class_loaded($class->stats_class);
1524 my $env = Catalyst::Utils::env_value( $class, 'STATS' );
1525 if ( defined($env) ? $env : ($stats || $class->debug ) ) {
1526 Class::MOP::get_metaclass_by_name($class)->add_method('use_stats' => sub { 1 });
1527 $class->log->debug('Statistics enabled');
1532 =head2 $c->registered_plugins
1534 Returns a sorted list of the plugins which have either been stated in the
1535 import list or which have been added via C<< MyApp->plugin(@args); >>.
1537 If passed a given plugin name, it will report a boolean value indicating
1538 whether or not that plugin is loaded. A fully qualified name is required if
1539 the plugin name does not begin with C<Catalyst::Plugin::>.
1541 if ($c->registered_plugins('Some::Plugin')) {
1549 sub registered_plugins {
1551 return sort keys %{ $proto->_plugins } unless @_;
1553 return 1 if exists $proto->_plugins->{$plugin};
1554 return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
1557 sub _register_plugin {
1558 my ( $proto, $plugin, $instant ) = @_;
1559 my $class = ref $proto || $proto;
1561 Class::MOP::load_class( $plugin );
1563 $proto->_plugins->{$plugin} = 1;
1566 if ( my $meta = Class::MOP::get_metaclass_by_name($class) ) {
1567 my @superclasses = ($plugin, $meta->superclasses );
1568 $meta->superclasses(@superclasses);
1570 unshift @{"$class\::ISA"}, $plugin;
1577 my ( $class, $plugins ) = @_;
1579 $class->_plugins( {} ) unless $class->_plugins;
1582 my @plugins = Catalyst::Utils::resolve_namespace($class . '::Plugin', 'Catalyst::Plugin', @$plugins);
1584 for my $plugin ( reverse @plugins ) {
1585 Class::MOP::load_class($plugin);
1586 my $meta = find_meta($plugin);
1587 next if $meta && $meta->isa('Moose::Meta::Role');
1589 $class->_register_plugin($plugin);
1594 grep { $_ && blessed($_) && $_->isa('Moose::Meta::Role') }
1595 map { find_meta($_) }
1598 Moose::Util::apply_all_roles(
1604 =head2 $c->stats_class
1606 Returns or sets the stats (timing statistics) class.
1608 =head2 $c->use_stats
1610 Returns 1 when stats collection is enabled. Stats collection is enabled
1611 when the -Stats options is set, debug is on or when the <MYAPP>_STATS
1612 environment variable is set.
1614 Note that this is a static method, not an accessor and should be overridden
1615 by declaring C<sub use_stats { 1 }> in your MyApp.pm, not by calling C<< $c->use_stats(1) >>.
1624 Returns the Catalyst version number. Mostly useful for "powered by"
1625 messages in template systems.
1629 sub version { return $Catalyst::VERSION }
1631 =head1 CONFIGURATION
1633 There are a number of 'base' config variables which can be set:
1639 C<case_sensitive> - Makes private paths case sensitive. See L</CASE SENSITIVITY>.
1643 C<default_model> - The default model picked if you say C<< $c->model >>. See L</$c->model($name)>.
1647 C<default_view> - The default view to be rendered or returned when C<< $c->view >>. See L</$c->view($name)>.
1652 C<disable_component_resolution_regex_fallback> - Turns
1653 off the deprecated component resolution functionality so
1654 that if any of the component methods (e.g. C<< $c->controller('Foo') >>)
1655 are called then regex search will not be attempted on string values and
1656 instead C<undef> will be returned.
1660 C<home> - The application home directory. In an uninstalled application,
1661 this is the top level application directory. In an installed application,
1662 this will be the directory containing C<< MyApp.pm >>.
1666 C<ignore_frontend_proxy> - See L</PROXY SUPPORT>
1670 C<name> - The name of the application in debug messages and the debug and
1675 C<parse_on_demand> - The request body (for example file uploads) will not be parsed
1676 until it is accessed. This allows you to (for example) check authentication (and reject
1677 the upload) before actually recieving all the data. See L</ON-DEMAND PARSER>
1681 C<root> - The root directory for templates. Usually this is just a
1682 subdirectory of the home directory, but you can set it to change the
1683 templates to a different directory.
1687 C<search_extra> - Array reference passed to Module::Pluggable to for additional
1688 namespaces from which components will be loaded (and constructed and stored in
1689 C<< $c->components >>).
1693 C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >>
1694 to be shown in hit debug tables in the test server.
1698 C<using_frontend_proxy> - See L</PROXY SUPPORT>.
1702 =head1 INTERNAL ACTIONS
1704 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
1705 C<_ACTION>, and C<_END>. These are by default not shown in the private
1706 action table, but you can make them visible with a config parameter.
1708 MyApp->config(show_internal_actions => 1);
1710 =head1 CASE SENSITIVITY
1712 By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
1713 mapped to C</foo/bar>. You can activate case sensitivity with a config
1716 MyApp->config(case_sensitive => 1);
1718 This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
1720 =head1 ON-DEMAND PARSER
1722 The request body is usually parsed at the beginning of a request,
1723 but if you want to handle input yourself, you can enable on-demand
1724 parsing with a config parameter.
1726 MyApp->config(parse_on_demand => 1);
1728 =head1 PROXY SUPPORT
1730 Many production servers operate using the common double-server approach,
1731 with a lightweight frontend web server passing requests to a larger
1732 backend server. An application running on the backend server must deal
1733 with two problems: the remote user always appears to be C<127.0.0.1> and
1734 the server's hostname will appear to be C<localhost> regardless of the
1735 virtual host that the user connected through.
1737 Catalyst will automatically detect this situation when you are running
1738 the frontend and backend servers on the same machine. The following
1739 changes are made to the request.
1741 $c->req->address is set to the user's real IP address, as read from
1742 the HTTP X-Forwarded-For header.
1744 The host value for $c->req->base and $c->req->uri is set to the real
1745 host, as read from the HTTP X-Forwarded-Host header.
1747 Additionally, you may be running your backend application on an insecure
1748 connection (port 80) while your frontend proxy is running under SSL. If there
1749 is a discrepancy in the ports, use the HTTP header C<X-Forwarded-Port> to
1750 tell Catalyst what port the frontend listens on. This will allow all URIs to
1751 be created properly.
1753 In the case of passing in:
1755 X-Forwarded-Port: 443
1757 All calls to C<uri_for> will result in an https link, as is expected.
1759 Obviously, your web server must support these headers for this to work.
1761 In a more complex server farm environment where you may have your
1762 frontend proxy server(s) on different machines, you will need to set a
1763 configuration option to tell Catalyst to read the proxied data from the
1766 MyApp->config(using_frontend_proxy => 1);
1768 If you do not wish to use the proxy support at all, you may set:
1770 MyApp->config(ignore_frontend_proxy => 1);
1772 =head1 THREAD SAFETY
1774 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
1775 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
1776 believe the Catalyst core to be thread-safe.
1778 If you plan to operate in a threaded environment, remember that all other
1779 modules you are using must also be thread-safe. Some modules, most notably
1780 L<DBD::SQLite>, are not thread-safe.
1786 Join #catalyst on irc.perl.org.
1790 http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
1791 http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
1795 http://catalyst.perl.org
1799 http://dev.catalyst.perl.org
1803 =head2 L<Task::Catalyst> - All you need to start with Catalyst
1805 =head2 L<Catalyst::Manual> - The Catalyst Manual
1807 =head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components
1809 =head2 L<Catalyst::Engine> - Core engine
1811 =head2 L<Catalyst::Log> - Log class.
1813 =head2 L<Catalyst::Request> - Request object
1815 =head2 L<Catalyst::Response> - Response object
1817 =head2 L<Catalyst::Test> - The test suite.
1819 =head1 PROJECT FOUNDER
1821 sri: Sebastian Riedel <sri@cpan.org>
1827 acme: Leon Brocard <leon@astray.com>
1829 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
1833 Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
1837 andyg: Andy Grundman <andy@hybridized.org>
1839 audreyt: Audrey Tang
1841 bricas: Brian Cassidy <bricas@cpan.org>
1843 Caelum: Rafael Kitover <rkitover@io.com>
1845 chansen: Christian Hansen
1847 chicks: Christopher Hicks
1849 Chisel Wright C<pause@herlpacker.co.uk>
1851 Danijel Milicevic C<me@danijel.de>
1853 David Kamholz E<lt>dkamholz@cpan.orgE<gt>
1855 David Naughton, C<naughton@umn.edu>
1859 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
1863 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
1865 esskar: Sascha Kiefer
1867 fireartist: Carl Franks <cfranks@cpan.org>
1869 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
1871 gabb: Danijel Milicevic
1875 Gavin Henry C<ghenry@perl.me.uk>
1879 groditi: Guillermo Roditi <groditi@gmail.com>
1881 hobbs: Andrew Rodland <andrew@cleverdomain.org>
1883 ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
1885 jcamacho: Juan Camacho
1887 jester: Jesse Sheidlower C<jester@panix.com>
1889 jhannah: Jay Hannah <jay@jays.net>
1895 jon: Jon Schutz <jjschutz@cpan.org>
1897 Jonathan Rockway C<< <jrockway@cpan.org> >>
1899 Kieren Diment C<kd@totaldatasolution.com>
1901 konobi: Scott McWhirter <konobi@cpan.org>
1903 marcus: Marcus Ramberg <mramberg@cpan.org>
1905 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
1907 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
1911 naughton: David Naughton
1913 ningu: David Kamholz <dkamholz@cpan.org>
1915 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
1917 numa: Dan Sully <daniel@cpan.org>
1921 omega: Andreas Marienborg
1923 Oleg Kostyuk <cub.uanic@gmail.com>
1925 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
1927 rafl: Florian Ragwitz <rafl@debian.org>
1929 random: Roland Lammel <lammel@cpan.org>
1931 Robert Sedlacek C<< <rs@474.at> >>
1935 t0m: Tomas Doran <bobtfish@bobtfish.net>
1939 Viljo Marrandi C<vilts@yahoo.com>
1941 Will Hawes C<info@whawes.co.uk>
1943 willert: Sebastian Willert <willert@cpan.org>
1945 Yuval Kogman, C<nothingmuch@woobling.org>
1949 This library is free software. You can redistribute it and/or modify it under
1950 the same terms as Perl itself.
1956 __PACKAGE__->meta->make_immutable;