4 use Moose::Meta::Class ();
5 extends 'Catalyst::Component';
6 use Moose::Util qw/find_meta/;
7 use B::Hooks::EndOfScope ();
8 use Catalyst::Exception;
11 use Catalyst::Controller;
12 use Devel::InnerPackage ();
13 use Module::Pluggable::Object ();
14 use Text::SimpleTable ();
15 use Path::Class::Dir ();
16 use Path::Class::File ();
17 use Tree::Simple::Visitor::FindByUID;
18 use Class::C3::Adopt::NEXT;
21 use Carp qw/croak carp shortmess/;
23 BEGIN { require 5.008004; }
25 sub comp { shift->component(@_) }
27 #I imagine that very few of these really need to be class variables. if any.
28 #maybe we should just make them attributes with a default?
29 __PACKAGE__->mk_classdata($_)
30 for qw/components arguments dispatcher engine log dispatcher_class
31 engine_class context_class request_class response_class stats_class
34 __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
35 __PACKAGE__->engine_class('Catalyst::Engine::CGI');
36 __PACKAGE__->request_class('Catalyst::Request');
37 __PACKAGE__->response_class('Catalyst::Response');
38 __PACKAGE__->stats_class('Catalyst::Stats');
40 # Remember to update this in Catalyst::Runtime as well!
42 our $VERSION = '5.80013';
45 my $dev_version = $VERSION =~ /_\d{2}$/;
46 *_IS_DEVELOPMENT_VERSION = sub () { $dev_version };
49 $VERSION = eval $VERSION;
55 my ( $class, @arguments ) = @_;
57 # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
59 return unless $class eq 'Catalyst';
61 my $caller = caller();
62 return if $caller eq 'main';
64 # Kill Adopt::NEXT warnings if we're a non-RC version
65 unless (_IS_DEVELOPMENT_VERSION()) {
66 Class::C3::Adopt::NEXT->unimport(qr/^Catalyst::/);
69 my $meta = Moose::Meta::Class->initialize($caller);
70 unless ( $caller->isa('Catalyst') ) {
71 my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
72 $meta->superclasses(@superclasses);
74 # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp
75 $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses);
77 unless( $meta->has_method('meta') ){
78 $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
81 $caller->arguments( [@arguments] );
85 sub _application { $_[0] }
89 Catalyst - The Elegant MVC Web Application Framework
93 See the L<Catalyst::Manual> distribution for comprehensive
94 documentation and tutorials.
96 # Install Catalyst::Devel for helpers and other development tools
97 # use the helper to create a new application
100 # add models, views, controllers
101 script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
102 script/myapp_create.pl view MyTemplate TT
103 script/myapp_create.pl controller Search
105 # built in testserver -- use -r to restart automatically on changes
106 # --help to see all available options
107 script/myapp_server.pl
109 # command line testing interface
110 script/myapp_test.pl /yada
113 use Catalyst qw/-Debug/; # include plugins here as well
115 ### In lib/MyApp/Controller/Root.pm (autocreated)
116 sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
117 my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
118 $c->stash->{template} = 'foo.tt'; # set the template
119 # lookup something from db -- stash vars are passed to TT
121 $c->model('Database::Foo')->search( { country => $args[0] } );
122 if ( $c->req->params->{bar} ) { # access GET or POST parameters
123 $c->forward( 'bar' ); # process another action
124 # do something else after forward returns
128 # The foo.tt TT template can use the stash data from the database
129 [% WHILE (item = data.next) %]
133 # called for /bar/of/soap, /bar/of/soap/10, etc.
134 sub bar : Path('/bar/of/soap') { ... }
136 # called for all actions, from the top-most controller downwards
138 my ( $self, $c ) = @_;
139 if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
140 $c->res->redirect( '/login' ); # require login
141 return 0; # abort request and go immediately to end()
143 return 1; # success; carry on to next action
146 # called after all actions are finished
148 my ( $self, $c ) = @_;
149 if ( scalar @{ $c->error } ) { ... } # handle errors
150 return if $c->res->body; # already have a response
151 $c->forward( 'MyApp::View::TT' ); # render template
154 ### in MyApp/Controller/Foo.pm
155 # called for /foo/bar
156 sub bar : Local { ... }
158 # called for /blargle
159 sub blargle : Global { ... }
161 # an index action matches /foo, but not /foo/1, etc.
162 sub index : Private { ... }
164 ### in MyApp/Controller/Foo/Bar.pm
165 # called for /foo/bar/baz
166 sub baz : Local { ... }
168 # first Root auto is called, then Foo auto, then this
169 sub auto : Private { ... }
171 # powerful regular expression paths are also possible
172 sub details : Regex('^product/(\w+)/details$') {
173 my ( $self, $c ) = @_;
174 # extract the (\w+) from the URI
175 my $product = $c->req->captures->[0];
178 See L<Catalyst::Manual::Intro> for additional information.
182 Catalyst is a modern framework for making web applications without the
183 pain usually associated with this process. This document is a reference
184 to the main Catalyst application. If you are a new user, we suggest you
185 start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
187 See L<Catalyst::Manual> for more documentation.
189 Catalyst plugins can be loaded by naming them as arguments to the "use
190 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
191 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
194 use Catalyst qw/My::Module/;
196 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
197 fully qualify the name by using a unary plus:
201 +Fully::Qualified::Plugin::Name
204 Special flags like C<-Debug> and C<-Engine> can also be specified as
205 arguments when Catalyst is loaded:
207 use Catalyst qw/-Debug My::Module/;
209 The position of plugins and flags in the chain is important, because
210 they are loaded in the order in which they appear.
212 The following flags are supported:
216 Enables debug output. You can also force this setting from the system
217 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
218 settings override the application, with <MYAPP>_DEBUG having the highest
223 Forces Catalyst to use a specific engine. Omit the
224 C<Catalyst::Engine::> prefix of the engine name, i.e.:
226 use Catalyst qw/-Engine=CGI/;
230 Forces Catalyst to use a specific home directory, e.g.:
232 use Catalyst qw[-Home=/usr/mst];
234 This can also be done in the shell environment by setting either the
235 C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
236 is replaced with the uppercased name of your application, any "::" in
237 the name will be replaced with underscores, e.g. MyApp::Web should use
238 MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
242 use Catalyst '-Log=warn,fatal,error';
244 Specifies a comma-delimited list of log levels.
248 Enables statistics collection and reporting. You can also force this setting
249 from the system environment with CATALYST_STATS or <MYAPP>_STATS. The
250 environment settings override the application, with <MYAPP>_STATS having the
255 use Catalyst qw/-Stats=1/
261 sub _comp_search_prefixes {
263 return map $c->components->{ $_ }, $c->_comp_names_search_prefixes(@_);
266 # search components given a name and some prefixes
267 sub _comp_names_search_prefixes {
268 my ( $c, $name, @prefixes ) = @_;
269 my $appclass = ref $c || $c;
270 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
271 $filter = qr/$filter/; # Compile regex now rather than once per loop
273 # map the original component name to the sub part that we will search against
274 my %eligible = map { my $n = $_; $n =~ s{^$appclass\::[^:]+::}{}; $_ => $n; }
275 grep { /$filter/ } keys %{ $c->components };
277 # undef for a name will return all
278 return keys %eligible if !defined $name;
280 my $query = ref $name ? $name : qr/^$name$/i;
281 my @result = grep { $eligible{$_} =~ m{$query} } keys %eligible;
283 return @result if @result;
285 # if we were given a regexp to search against, we're done.
288 # skip regexp fallback if configured
290 if $appclass->config->{disable_component_resolution_regex_fallback};
294 @result = grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
296 # no results? try against full names
298 @result = grep { m{$query} } keys %eligible;
301 # don't warn if we didn't find any results, it just might not exist
303 # Disgusting hack to work out correct method name
304 my $warn_for = lc $prefixes[0];
305 my $msg = "Used regexp fallback for \$c->${warn_for}('${name}'), which found '" .
306 (join '", "', @result) . "'. Relying on regexp fallback behavior for " .
307 "component resolution is unreliable and unsafe.";
308 my $short = $result[0];
309 # remove the component namespace prefix
310 $short =~ s/.*?(Model|Controller|View):://;
311 my $shortmess = Carp::shortmess('');
312 if ($shortmess =~ m#Catalyst/Plugin#) {
313 $msg .= " You probably need to set '$short' instead of '${name}' in this " .
315 } elsif ($shortmess =~ m#Catalyst/lib/(View|Controller)#) {
316 $msg .= " You probably need to set '$short' instead of '${name}' in this " .
317 "component's config";
319 $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}('${name}'), " .
320 "but if you really wanted to search, pass in a regexp as the argument " .
321 "like so: \$c->${warn_for}(qr/${name}/)";
323 $c->log->warn( "${msg}$shortmess" );
329 # Find possible names for a prefix
331 my ( $c, @prefixes ) = @_;
332 my $appclass = ref $c || $c;
334 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
336 my @names = map { s{$filter}{}; $_; }
337 $c->_comp_names_search_prefixes( undef, @prefixes );
342 # Filter a component before returning by calling ACCEPT_CONTEXT if available
343 sub _filter_component {
344 my ( $c, $comp, @args ) = @_;
346 if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) {
347 return $comp->ACCEPT_CONTEXT( $c, @args );
353 =head2 COMPONENT ACCESSORS
355 =head2 $c->controllers
357 Returns the available names which can be passed to $c->controller
363 return $c->_comp_names(qw/Controller C/);
368 Returns the available names which can be passed to $c->model
374 return $c->_comp_names(qw/Model M/);
380 Returns the available names which can be passed to $c->view
386 return $c->_comp_names(qw/View V/);
389 =head2 $c->comp($name)
391 =head2 $c->component($name)
393 Gets a component object by name. This method is not recommended,
394 unless you want to get a specific component by full
395 class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >>
396 should be used instead.
398 If C<$name> is a regexp, a list of components matched against the full
399 component name will be returned.
401 If Catalyst can't find a component by name, it will fallback to regex
402 matching by default. To disable this behaviour set
403 disable_component_resolution_regex_fallback to a true value.
405 __PACKAGE__->config( disable_component_resolution_regex_fallback => 1 );
410 my ( $c, $name, @args ) = @_;
413 my $comps = $c->components;
416 # is it the exact name?
417 return $c->_filter_component( $comps->{ $name }, @args )
418 if exists $comps->{ $name };
420 # perhaps we just omitted "MyApp"?
421 my $composed = ( ref $c || $c ) . "::${name}";
422 return $c->_filter_component( $comps->{ $composed }, @args )
423 if exists $comps->{ $composed };
425 # search all of the models, views and controllers
426 my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ );
427 return $c->_filter_component( $comp, @args ) if $comp;
430 # This is here so $c->comp( '::M::' ) works
431 my $query = ref $name ? $name : qr{$name}i;
433 my @result = grep { m{$query} } keys %{ $c->components };
434 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
437 $c->log->warn( Carp::shortmess(qq(Found results for "${name}" using regexp fallback)) );
438 $c->log->warn( 'Relying on the regexp fallback behavior for component resolution' );
439 $c->log->warn( 'is unreliable and unsafe. You have been warned' );
440 return $c->_filter_component( $result[ 0 ], @args );
443 # I would expect to return an empty list here, but that breaks back-compat
447 return sort keys %{ $c->components };
450 =head2 CLASS DATA AND HELPER CLASSES
454 Returns or takes a hashref containing the application's configuration.
456 __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
458 You can also use a C<YAML>, C<XML> or L<Config::General> config file
459 like C<myapp.conf> in your applications home directory. See
460 L<Catalyst::Plugin::ConfigLoader>.
462 =head3 Cascading configuration
464 The config method is present on all Catalyst components, and configuration
465 will be merged when an application is started. Configuration loaded with
466 L<Catalyst::Plugin::ConfigLoader> takes precedence over other configuration,
467 followed by configuration in your top level C<MyApp> class. These two
468 configurations are merged, and then configuration data whose hash key matches a
469 component name is merged with configuration for that component.
471 The configuration for a component is then passed to the C<new> method when a
472 component is constructed.
476 MyApp->config({ 'Model::Foo' => { bar => 'baz', overrides => 'me' } });
477 MyApp::Model::Foo->config({ quux => 'frob', 'overrides => 'this' });
479 will mean that C<MyApp::Model::Foo> receives the following data when
482 MyApp::Model::Foo->new({
490 around config => sub {
494 croak('Setting config after setup has been run is not allowed.')
495 if ( @_ and $c->setup_finished );
502 Returns the logging object instance. Unless it is already set, Catalyst
503 sets this up with a L<Catalyst::Log> object. To use your own log class,
504 set the logger with the C<< __PACKAGE__->log >> method prior to calling
505 C<< __PACKAGE__->setup >>.
507 __PACKAGE__->log( MyLogger->new );
512 $c->log->info( 'Now logging with my own logger!' );
514 Your log class should implement the methods described in
520 Returns 1 if debug mode is enabled, 0 otherwise.
522 You can enable debug mode in several ways:
526 =item By calling myapp_server.pl with the -d flag
528 =item With the environment variables MYAPP_DEBUG, or CATALYST_DEBUG
530 =item The -Debug option in your MyApp.pm
532 =item By declaring C<sub debug { 1 }> in your MyApp.pm.
536 Calling C<< $c->debug(1) >> has no effect.
542 =head2 $c->dispatcher
544 Returns the dispatcher instance. See L<Catalyst::Dispatcher>.
548 Returns the engine instance. See L<Catalyst::Engine>.
551 =head2 UTILITY METHODS
553 =head2 $c->path_to(@path)
555 Merges C<@path> with C<< $c->config->{home} >> and returns a
556 L<Path::Class::Dir> object. Note you can usually use this object as
557 a filename, but sometimes you will have to explicitly stringify it
558 yourself by calling the C<< ->stringify >> method.
562 $c->path_to( 'db', 'sqlite.db' );
567 my ( $c, @path ) = @_;
568 my $path = Path::Class::Dir->new( $c->config->{home}, @path );
569 if ( -d $path ) { return $path }
570 else { return Path::Class::File->new( $c->config->{home}, @path ) }
573 =head2 $c->plugin( $name, $class, @args )
575 Helper method for plugins. It creates a class data accessor/mutator and
576 loads and instantiates the given class.
578 MyApp->plugin( 'prototype', 'HTML::Prototype' );
580 $c->prototype->define_javascript_functions;
582 B<Note:> This method of adding plugins is deprecated. The ability
583 to add plugins like this B<will be removed> in a Catalyst 5.81.
584 Please do not use this functionality in new code.
589 my ( $class, $name, $plugin, @args ) = @_;
591 # See block comment in t/unit_core_plugin.t
592 $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in Catalyst 5.81/);
594 $class->_register_plugin( $plugin, 1 );
596 eval { $plugin->import };
597 $class->mk_classdata($name);
599 eval { $obj = $plugin->new(@args) };
602 Catalyst::Exception->throw( message =>
603 qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
607 $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
613 Initializes the dispatcher and engine, loads any plugins, and loads the
614 model, view, and controller components. You may also specify an array
615 of plugins to load here, if you choose to not load them in the C<use
619 MyApp->setup( qw/-Debug/ );
624 my ( $class, @arguments ) = @_;
625 croak('Running setup more than once')
626 if ( $class->setup_finished );
628 unless ( $class->isa('Catalyst') ) {
630 Catalyst::Exception->throw(
631 message => qq/'$class' does not inherit from Catalyst/ );
634 if ( $class->arguments ) {
635 @arguments = ( @arguments, @{ $class->arguments } );
641 foreach (@arguments) {
645 ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
647 elsif (/^-(\w+)=?(.*)$/) {
648 $flags->{ lc $1 } = $2;
651 push @{ $flags->{plugins} }, $_;
655 $class->setup_home( delete $flags->{home} );
657 $class->setup_log( delete $flags->{log} );
658 $class->setup_plugins( delete $flags->{plugins} );
659 $class->setup_dispatcher( delete $flags->{dispatcher} );
660 $class->setup_engine( delete $flags->{engine} );
661 $class->setup_stats( delete $flags->{stats} );
663 for my $flag ( sort keys %{$flags} ) {
665 if ( my $code = $class->can( 'setup_' . $flag ) ) {
666 &$code( $class, delete $flags->{$flag} );
669 $class->log->warn(qq/Unknown flag "$flag"/);
673 eval { require Catalyst::Devel; };
674 if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
675 $class->log->warn(<<"EOF");
676 You are running an old script!
678 Please update by running (this will overwrite existing files):
679 catalyst.pl -force -scripts $class
681 or (this will not overwrite existing files):
682 catalyst.pl -scripts $class
687 if ( $class->debug ) {
688 my @plugins = map { "$_ " . ( $_->VERSION || '' ) } $class->registered_plugins;
691 my $column_width = Catalyst::Utils::term_width() - 6;
692 my $t = Text::SimpleTable->new($column_width);
693 $t->row($_) for @plugins;
694 $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
697 my $dispatcher = $class->dispatcher;
698 my $engine = $class->engine;
699 my $home = $class->config->{home};
701 $class->log->debug(sprintf(q/Loaded dispatcher "%s"/, blessed($dispatcher)));
702 $class->log->debug(sprintf(q/Loaded engine "%s"/, blessed($engine)));
706 ? $class->log->debug(qq/Found home "$home"/)
707 : $class->log->debug(qq/Home "$home" doesn't exist/)
708 : $class->log->debug(q/Couldn't find home/);
711 # Call plugins setup, this is stupid and evil.
712 # Also screws C3 badly on 5.10, hack to avoid.
714 no warnings qw/redefine/;
715 local *setup = sub { };
716 $class->setup unless $Catalyst::__AM_RESTARTING;
719 # Initialize our data structure
720 $class->components( {} );
722 $class->setup_components;
724 if ( $class->debug ) {
725 my $column_width = Catalyst::Utils::term_width() - 8 - 9;
726 my $t = Text::SimpleTable->new( [ $column_width, 'Class' ], [ 8, 'Type' ] );
727 for my $comp ( sort keys %{ $class->components } ) {
728 my $type = ref $class->components->{$comp} ? 'instance' : 'class';
729 $t->row( $comp, $type );
731 $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
732 if ( keys %{ $class->components } );
735 # Add our self to components, since we are also a component
736 if( $class->isa('Catalyst::Controller') ){
737 $class->components->{$class} = $class;
740 $class->setup_actions;
742 if ( $class->debug ) {
743 my $name = $class->config->{name} || 'Application';
744 $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
747 # Make sure that the application class becomes immutable at this point,
748 B::Hooks::EndOfScope::on_scope_end {
750 my $meta = Class::MOP::get_metaclass_by_name($class);
753 && ! { $meta->immutable_options }->{replace_constructor}
755 $class->isa('Class::Accessor::Fast')
756 || $class->isa('Class::Accessor')
759 warn "You made your application class ($class) immutable, "
760 . "but did not inline the\nconstructor. "
761 . "This will break catalyst, as your app \@ISA "
762 . "Class::Accessor(::Fast)?\nPlease pass "
763 . "(replace_constructor => 1)\nwhen making your class immutable.\n";
765 $meta->make_immutable(
766 replace_constructor => 1,
767 ) unless $meta->is_immutable;
770 $class->setup_finalize;
771 # Should be the last thing we do so that user things hooking
772 # setup_finalize can log..
773 $class->log->_flush() if $class->log->can('_flush');
774 return 1; # Explicit return true as people have __PACKAGE__->setup as the last thing in their class. HATE.
778 =head2 $app->setup_finalize
780 A hook to attach modifiers to.
781 Using C<< after setup => sub{}; >> doesn't work, because of quirky things done for plugin setup.
782 Also better than C< setup_finished(); >, as that is a getter method.
788 ## do stuff, i.e., determine a primary key column for sessions stored in a DB
790 $app->next::method(@_);
799 $class->setup_finished(1);
802 =head2 $c->welcome_message
804 Returns the Catalyst welcome HTML page.
808 sub welcome_message {
810 my $name = $c->config->{name};
811 my $logo = $c->uri_for('/static/images/catalyst_logo.png');
812 my $prefix = Catalyst::Utils::appprefix( ref $c );
813 $c->response->content_type('text/html; charset=utf-8');
815 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
816 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
817 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
819 <meta http-equiv="Content-Language" content="en" />
820 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
821 <title>$name on Catalyst $VERSION</title>
822 <style type="text/css">
825 background-color: #eee;
834 background-color: #ccc;
835 border: 1px solid #aaa;
840 font-family: verdana, tahoma, sans-serif;
843 font-family: verdana, tahoma, sans-serif;
846 text-decoration: none;
848 border-bottom: 1px dotted #bbb;
850 :link:hover, :visited:hover {
863 background-color: #fff;
864 border: 1px solid #aaa;
890 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
895 <img src="$logo" alt="Catalyst Logo" />
897 <p>Welcome to the world of Catalyst.
898 This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
899 framework will make web development something you had
900 never expected it to be: Fun, rewarding, and quick.</p>
901 <h2>What to do now?</h2>
902 <p>That really depends on what <b>you</b> want to do.
903 We do, however, provide you with a few starting points.</p>
904 <p>If you want to jump right into web development with Catalyst
905 you might want to start with a tutorial.</p>
906 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
908 <p>Afterwards you can go on to check out a more complete look at our features.</p>
910 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
911 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
913 <h2>What to do next?</h2>
914 <p>Next it's time to write an actual application. Use the
915 helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&mode=all">controllers</a>,
916 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&mode=all">models</a>, and
917 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&mode=all">views</a>;
918 they can save you a lot of work.</p>
919 <pre><code>script/${prefix}_create.pl -help</code></pre>
920 <p>Also, be sure to check out the vast and growing
921 collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
922 you are likely to find what you need there.
926 <p>Catalyst has a very active community. Here are the main places to
927 get in touch with us.</p>
930 <a href="http://dev.catalyst.perl.org">Wiki</a>
933 <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a>
936 <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
939 <h2>In conclusion</h2>
940 <p>The Catalyst team hopes you will enjoy using Catalyst as much
941 as we enjoyed making it. Please contact us if you have ideas
942 for improvement or other feedback.</p>
950 =head1 INTERNAL METHODS
952 These methods are not meant to be used by end users.
954 =head2 $c->components
956 Returns a hash of components.
958 =head2 $c->context_class
960 Returns or sets the context class.
962 =head2 $c->dispatcher_class
964 Returns or sets the dispatcher class.
966 =head2 $c->engine_class
968 Returns or sets the engine class.
970 =head2 $c->handle_request( $class, @arguments )
972 Called to handle each HTTP request.
977 my ( $class, @arguments ) = @_;
979 # Always expect worst case!
983 my $secs = time - $START || 1;
984 my $av = sprintf '%.3f', $COUNT / $secs;
985 my $time = localtime time;
986 $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
989 my $c = $class->prepare(@arguments);
991 $status = $c->finalize;
994 if ( my $error = $@ ) {
996 $class->log->error(qq/Caught exception in engine "$error"/);
1001 if(my $coderef = $class->log->can('_flush')){
1002 $class->log->$coderef();
1007 =head2 $c->prepare( @arguments )
1009 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1015 my ( $class, @arguments ) = @_;
1018 # After the app/ctxt split, this should become an attribute based on something passed
1019 # into the application.
1020 $class->context_class( ref $class || $class ) unless $class->context_class;
1022 my $c = $class->context_class->new({});
1024 # For on-demand data
1025 $c->request->_context($c);
1026 $c->response->_context($c);
1028 #surely this is not the most efficient way to do things...
1029 $c->stats($class->stats_class->new)->enable($c->use_stats);
1031 $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
1034 #XXX reuse coderef from can
1035 # Allow engine to direct the prepare flow (for POE)
1036 if ( $c->engine->can('prepare') ) {
1037 $c->engine->prepare( $c, @arguments );
1040 $c->prepare_request(@arguments);
1041 $c->prepare_connection;
1042 $c->prepare_query_parameters;
1043 $c->prepare_headers;
1044 $c->prepare_cookies;
1047 # Prepare the body for reading, either by prepare_body
1048 # or the user, if they are using $c->read
1051 # Parse the body unless the user wants it on-demand
1052 unless ( ref($c)->config->{parse_on_demand} ) {
1057 my $method = $c->req->method || '';
1058 my $path = $c->req->path;
1059 $path = '/' unless length $path;
1060 my $address = $c->req->address || '';
1062 $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1070 =head2 $c->request_class
1072 Returns or sets the request class.
1074 =head2 $c->response_class
1076 Returns or sets the response class.
1084 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1086 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1088 Sets an action in a given namespace.
1092 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1094 =head2 $c->setup_actions($component)
1096 Sets up actions for a component.
1100 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1102 =head2 $c->setup_components
1104 This method is called internally to set up the application's components.
1106 It finds modules by calling the L<locate_components> method, expands them to
1107 package names with the L<expand_component_module> method, and then installs
1108 each component into the application.
1110 The C<setup_components> config option is passed to both of the above methods.
1112 Installation of each component is performed by the L<setup_component> method,
1117 sub setup_components {
1120 my $config = $class->config->{ setup_components };
1122 my @comps = sort { length $a <=> length $b }
1123 $class->locate_components($config);
1124 my %comps = map { $_ => 1 } @comps;
1126 my $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @comps;
1127 $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
1128 qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
1129 ) if $deprecatedcatalyst_component_names;
1131 for my $component ( @comps ) {
1133 # We pass ignore_loaded here so that overlay files for (e.g.)
1134 # Model::DBI::Schema sub-classes are loaded - if it's in @comps
1135 # we know M::P::O found a file on disk so this is safe
1137 Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
1139 # Needs to be done as soon as the component is loaded, as loading a sub-component
1140 # (next time round the loop) can cause us to get the wrong metaclass..
1141 $class->_controller_init_base_classes($component);
1144 for my $component (@comps) {
1145 $class->components->{ $component } = $class->setup_component($component);
1146 for my $component ($class->expand_component_module( $component, $config )) {
1147 next if $comps{$component};
1148 $class->_controller_init_base_classes($component); # Also cover inner packages
1149 $class->components->{ $component } = $class->setup_component($component);
1154 =head2 $c->locate_components( $setup_component_config )
1156 This method is meant to provide a list of component modules that should be
1157 setup for the application. By default, it will use L<Module::Pluggable>.
1159 Specify a C<setup_components> config option to pass additional options directly
1160 to L<Module::Pluggable>. To add additional search paths, specify a key named
1161 C<search_extra> as an array reference. Items in the array beginning with C<::>
1162 will have the application class name prepended to them.
1166 sub locate_components {
1170 my @paths = qw( ::Controller ::C ::Model ::M ::View ::V );
1171 my $extra = delete $config->{ search_extra } || [];
1173 push @paths, @$extra;
1175 my $locator = Module::Pluggable::Object->new(
1176 search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
1180 my @comps = $locator->plugins;
1185 =head2 $c->expand_component_module( $component, $setup_component_config )
1187 Components found by C<locate_components> will be passed to this method, which
1188 is expected to return a list of component (package) names to be set up.
1192 sub expand_component_module {
1193 my ($class, $module) = @_;
1194 return Devel::InnerPackage::list_packages( $module );
1197 =head2 $c->setup_component
1201 # FIXME - Ugly, ugly hack to ensure the we force initialize non-moose base classes
1202 # nearest to Catalyst::Controller first, no matter what order stuff happens
1203 # to be loaded. There are TODO tests in Moose for this, see
1204 # f2391d17574eff81d911b97be15ea51080500003
1205 sub _controller_init_base_classes {
1206 my ($app_class, $component) = @_;
1207 return unless $component->isa('Catalyst::Controller');
1208 foreach my $class ( reverse @{ mro::get_linear_isa($component) } ) {
1209 Moose::Meta::Class->initialize( $class )
1210 unless find_meta($class);
1214 sub setup_component {
1215 my( $class, $component ) = @_;
1217 unless ( $component->can( 'COMPONENT' ) ) {
1221 my $suffix = Catalyst::Utils::class2classsuffix( $component );
1222 my $config = $class->config->{ $suffix } || {};
1223 # Stash catalyst_component_name in the config here, so that custom COMPONENT
1224 # methods also pass it. local to avoid pointlessly shitting in config
1225 # for the debug screen, as $component is already the key name.
1226 local $config->{catalyst_component_name} = $component;
1228 my $instance = eval { $component->COMPONENT( $class, $config ); };
1230 if ( my $error = $@ ) {
1232 Catalyst::Exception->throw(
1233 message => qq/Couldn't instantiate component "$component", "$error"/
1237 unless (blessed $instance) {
1238 my $metaclass = Moose::Util::find_meta($component);
1239 my $method_meta = $metaclass->find_method_by_name('COMPONENT');
1240 my $component_method_from = $method_meta->associated_metaclass->name;
1241 my $value = defined($instance) ? $instance : 'undef';
1242 Catalyst::Exception->throw(
1244 qq/Couldn't instantiate component "$component", COMPONENT() method (from $component_method_from) didn't return an object-like value (value was $value)./
1250 =head2 $c->setup_dispatcher
1256 sub setup_dispatcher {
1257 my ( $class, $dispatcher ) = @_;
1260 $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
1263 if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
1264 $dispatcher = 'Catalyst::Dispatcher::' . $env;
1267 unless ($dispatcher) {
1268 $dispatcher = $class->dispatcher_class;
1271 Class::MOP::load_class($dispatcher);
1273 # dispatcher instance
1274 $class->dispatcher( $dispatcher->new );
1277 =head2 $c->setup_engine
1284 my ( $class, $engine ) = @_;
1287 $engine = 'Catalyst::Engine::' . $engine;
1290 if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
1291 $engine = 'Catalyst::Engine::' . $env;
1294 if ( $ENV{MOD_PERL} ) {
1295 my $meta = Class::MOP::get_metaclass_by_name($class);
1297 # create the apache method
1298 $meta->add_method('apache' => sub { shift->engine->apache });
1300 my ( $software, $version ) =
1301 $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
1304 $version =~ s/(\.[^.]+)\./$1/g;
1306 if ( $software eq 'mod_perl' ) {
1310 if ( $version >= 1.99922 ) {
1311 $engine = 'Catalyst::Engine::Apache2::MP20';
1314 elsif ( $version >= 1.9901 ) {
1315 $engine = 'Catalyst::Engine::Apache2::MP19';
1318 elsif ( $version >= 1.24 ) {
1319 $engine = 'Catalyst::Engine::Apache::MP13';
1323 Catalyst::Exception->throw( message =>
1324 qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
1329 # install the correct mod_perl handler
1330 if ( $version >= 1.9901 ) {
1331 *handler = sub : method {
1332 shift->handle_request(@_);
1336 *handler = sub ($$) { shift->handle_request(@_) };
1341 elsif ( $software eq 'Zeus-Perl' ) {
1342 $engine = 'Catalyst::Engine::Zeus';
1346 Catalyst::Exception->throw(
1347 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
1352 $engine = $class->engine_class;
1355 Class::MOP::load_class($engine);
1357 # check for old engines that are no longer compatible
1359 if ( $engine->isa('Catalyst::Engine::Apache')
1360 && !Catalyst::Engine::Apache->VERSION )
1365 elsif ( $engine->isa('Catalyst::Engine::Server::Base')
1366 && Catalyst::Engine::Server->VERSION le '0.02' )
1371 elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
1372 && $engine->VERSION eq '0.01' )
1377 elsif ($engine->isa('Catalyst::Engine::Zeus')
1378 && $engine->VERSION eq '0.01' )
1384 Catalyst::Exception->throw( message =>
1385 qq/Engine "$engine" is not supported by this version of Catalyst/
1390 $class->engine( $engine->new );
1393 =head2 $c->setup_home
1395 Sets up the home directory.
1400 my ( $class, $home ) = @_;
1402 if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
1406 $home ||= Catalyst::Utils::home($class);
1409 #I remember recently being scolded for assigning config values like this
1410 $class->config->{home} ||= $home;
1411 $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
1415 =head2 $c->setup_log
1417 Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and
1418 passing it to C<log()>. Pass in a comma-delimited list of levels to set the
1421 This method also installs a C<debug> method that returns a true value into the
1422 catalyst subclass if the "debug" level is passed in the comma-delimited list,
1423 or if the C<$CATALYST_DEBUG> environment variable is set to a true value.
1425 Note that if the log has already been setup, by either a previous call to
1426 C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>,
1427 that this method won't actually set up the log object.
1432 my ( $class, $levels ) = @_;
1435 $levels =~ s/^\s+//;
1436 $levels =~ s/\s+$//;
1437 my %levels = map { $_ => 1 } split /\s*,\s*/, $levels;
1439 my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
1440 if ( defined $env_debug ) {
1441 $levels{debug} = 1 if $env_debug; # Ugly!
1442 delete($levels{debug}) unless $env_debug;
1445 unless ( $class->log ) {
1446 $class->log( Catalyst::Log->new(keys %levels) );
1449 if ( $levels{debug} ) {
1450 Class::MOP::get_metaclass_by_name($class)->add_method('debug' => sub { 1 });
1451 $class->log->debug('Debug messages enabled');
1455 =head2 $c->setup_plugins
1461 =head2 $c->setup_stats
1463 Sets up timing statistics class.
1468 my ( $class, $stats ) = @_;
1470 Catalyst::Utils::ensure_class_loaded($class->stats_class);
1472 my $env = Catalyst::Utils::env_value( $class, 'STATS' );
1473 if ( defined($env) ? $env : ($stats || $class->debug ) ) {
1474 Class::MOP::get_metaclass_by_name($class)->add_method('use_stats' => sub { 1 });
1475 $class->log->debug('Statistics enabled');
1480 =head2 $c->registered_plugins
1482 Returns a sorted list of the plugins which have either been stated in the
1483 import list or which have been added via C<< MyApp->plugin(@args); >>.
1485 If passed a given plugin name, it will report a boolean value indicating
1486 whether or not that plugin is loaded. A fully qualified name is required if
1487 the plugin name does not begin with C<Catalyst::Plugin::>.
1489 if ($c->registered_plugins('Some::Plugin')) {
1497 sub registered_plugins {
1499 return sort keys %{ $proto->_plugins } unless @_;
1501 return 1 if exists $proto->_plugins->{$plugin};
1502 return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
1505 sub _register_plugin {
1506 my ( $proto, $plugin, $instant ) = @_;
1507 my $class = ref $proto || $proto;
1509 Class::MOP::load_class( $plugin );
1511 $proto->_plugins->{$plugin} = 1;
1514 if ( my $meta = Class::MOP::get_metaclass_by_name($class) ) {
1515 my @superclasses = ($plugin, $meta->superclasses );
1516 $meta->superclasses(@superclasses);
1518 unshift @{"$class\::ISA"}, $plugin;
1525 my ( $class, $plugins ) = @_;
1527 $class->_plugins( {} ) unless $class->_plugins;
1530 my @plugins = Catalyst::Utils::resolve_namespace($class . '::Plugin', 'Catalyst::Plugin', @$plugins);
1532 for my $plugin ( reverse @plugins ) {
1533 Class::MOP::load_class($plugin);
1534 my $meta = find_meta($plugin);
1535 next if $meta && $meta->isa('Moose::Meta::Role');
1537 $class->_register_plugin($plugin);
1542 grep { $_ && blessed($_) && $_->isa('Moose::Meta::Role') }
1543 map { find_meta($_) }
1546 Moose::Util::apply_all_roles(
1552 =head2 $c->stats_class
1554 Returns or sets the stats (timing statistics) class.
1556 =head2 $c->use_stats
1558 Returns 1 when stats collection is enabled. Stats collection is enabled
1559 when the -Stats options is set, debug is on or when the <MYAPP>_STATS
1560 environment variable is set.
1562 Note that this is a static method, not an accessor and should be overridden
1563 by declaring C<sub use_stats { 1 }> in your MyApp.pm, not by calling C<< $c->use_stats(1) >>.
1571 Returns the Catalyst version number. Mostly useful for "powered by"
1572 messages in template systems.
1576 sub version { return $Catalyst::VERSION }
1578 =head1 CONFIGURATION
1580 There are a number of 'base' config variables which can be set:
1586 C<default_model> - The default model picked if you say C<< $c->model >>. See L</$c->model($name)>.
1590 C<default_view> - The default view to be rendered or returned when C<< $c->view >>. See L</$c->view($name)>.
1595 C<disable_component_resolution_regex_fallback> - Turns
1596 off the deprecated component resolution functionality so
1597 that if any of the component methods (e.g. C<< $c->controller('Foo') >>)
1598 are called then regex search will not be attempted on string values and
1599 instead C<undef> will be returned.
1603 C<home> - The application home directory. In an uninstalled application,
1604 this is the top level application directory. In an installed application,
1605 this will be the directory containing C<< MyApp.pm >>.
1609 C<ignore_frontend_proxy> - See L</PROXY SUPPORT>
1613 C<name> - The name of the application in debug messages and the debug and
1618 C<parse_on_demand> - The request body (for example file uploads) will not be parsed
1619 until it is accessed. This allows you to (for example) check authentication (and reject
1620 the upload) before actually recieving all the data. See L</ON-DEMAND PARSER>
1624 C<root> - The root directory for templates. Usually this is just a
1625 subdirectory of the home directory, but you can set it to change the
1626 templates to a different directory.
1630 C<search_extra> - Array reference passed to Module::Pluggable to for additional
1631 namespaces from which components will be loaded (and constructed and stored in
1632 C<< $c->components >>).
1636 C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >>
1637 to be shown in hit debug tables in the test server.
1641 C<using_frontend_proxy> - See L</PROXY SUPPORT>.
1645 =head1 INTERNAL ACTIONS
1647 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
1648 C<_ACTION>, and C<_END>. These are by default not shown in the private
1649 action table, but you can make them visible with a config parameter.
1651 MyApp->config(show_internal_actions => 1);
1653 =head1 ON-DEMAND PARSER
1655 The request body is usually parsed at the beginning of a request,
1656 but if you want to handle input yourself, you can enable on-demand
1657 parsing with a config parameter.
1659 MyApp->config(parse_on_demand => 1);
1661 =head1 PROXY SUPPORT
1663 Many production servers operate using the common double-server approach,
1664 with a lightweight frontend web server passing requests to a larger
1665 backend server. An application running on the backend server must deal
1666 with two problems: the remote user always appears to be C<127.0.0.1> and
1667 the server's hostname will appear to be C<localhost> regardless of the
1668 virtual host that the user connected through.
1670 Catalyst will automatically detect this situation when you are running
1671 the frontend and backend servers on the same machine. The following
1672 changes are made to the request.
1674 $c->req->address is set to the user's real IP address, as read from
1675 the HTTP X-Forwarded-For header.
1677 The host value for $c->req->base and $c->req->uri is set to the real
1678 host, as read from the HTTP X-Forwarded-Host header.
1680 Additionally, you may be running your backend application on an insecure
1681 connection (port 80) while your frontend proxy is running under SSL. If there
1682 is a discrepancy in the ports, use the HTTP header C<X-Forwarded-Port> to
1683 tell Catalyst what port the frontend listens on. This will allow all URIs to
1684 be created properly.
1686 In the case of passing in:
1688 X-Forwarded-Port: 443
1690 All calls to C<uri_for> will result in an https link, as is expected.
1692 Obviously, your web server must support these headers for this to work.
1694 In a more complex server farm environment where you may have your
1695 frontend proxy server(s) on different machines, you will need to set a
1696 configuration option to tell Catalyst to read the proxied data from the
1699 MyApp->config(using_frontend_proxy => 1);
1701 If you do not wish to use the proxy support at all, you may set:
1703 MyApp->config(ignore_frontend_proxy => 1);
1705 =head1 THREAD SAFETY
1707 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
1708 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
1709 believe the Catalyst core to be thread-safe.
1711 If you plan to operate in a threaded environment, remember that all other
1712 modules you are using must also be thread-safe. Some modules, most notably
1713 L<DBD::SQLite>, are not thread-safe.
1719 Join #catalyst on irc.perl.org.
1723 http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
1724 http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
1728 http://catalyst.perl.org
1732 http://dev.catalyst.perl.org
1736 =head2 L<Task::Catalyst> - All you need to start with Catalyst
1738 =head2 L<Catalyst::Manual> - The Catalyst Manual
1740 =head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components
1742 =head2 L<Catalyst::Engine> - Core engine
1744 =head2 L<Catalyst::Log> - Log class.
1746 =head2 L<Catalyst::Request> - Request object
1748 =head2 L<Catalyst::Response> - Response object
1750 =head2 L<Catalyst::Test> - The test suite.
1752 =head1 PROJECT FOUNDER
1754 sri: Sebastian Riedel <sri@cpan.org>
1760 acme: Leon Brocard <leon@astray.com>
1762 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
1766 Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
1770 andyg: Andy Grundman <andy@hybridized.org>
1772 audreyt: Audrey Tang
1774 bricas: Brian Cassidy <bricas@cpan.org>
1776 Caelum: Rafael Kitover <rkitover@io.com>
1778 chansen: Christian Hansen
1780 chicks: Christopher Hicks
1782 Chisel Wright C<pause@herlpacker.co.uk>
1784 Danijel Milicevic C<me@danijel.de>
1786 David Kamholz E<lt>dkamholz@cpan.orgE<gt>
1788 David Naughton, C<naughton@umn.edu>
1792 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
1796 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
1798 esskar: Sascha Kiefer
1800 fireartist: Carl Franks <cfranks@cpan.org>
1802 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
1804 gabb: Danijel Milicevic
1808 Gavin Henry C<ghenry@perl.me.uk>
1812 groditi: Guillermo Roditi <groditi@gmail.com>
1814 hobbs: Andrew Rodland <andrew@cleverdomain.org>
1816 ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
1818 jcamacho: Juan Camacho
1820 jester: Jesse Sheidlower C<jester@panix.com>
1822 jhannah: Jay Hannah <jay@jays.net>
1828 jon: Jon Schutz <jjschutz@cpan.org>
1830 Jonathan Rockway C<< <jrockway@cpan.org> >>
1832 Kieren Diment C<kd@totaldatasolution.com>
1834 konobi: Scott McWhirter <konobi@cpan.org>
1836 marcus: Marcus Ramberg <mramberg@cpan.org>
1838 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
1840 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
1844 naughton: David Naughton
1846 ningu: David Kamholz <dkamholz@cpan.org>
1848 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
1850 numa: Dan Sully <daniel@cpan.org>
1854 omega: Andreas Marienborg
1856 Oleg Kostyuk <cub.uanic@gmail.com>
1858 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
1860 rafl: Florian Ragwitz <rafl@debian.org>
1862 random: Roland Lammel <lammel@cpan.org>
1864 Robert Sedlacek C<< <rs@474.at> >>
1868 t0m: Tomas Doran <bobtfish@bobtfish.net>
1872 Viljo Marrandi C<vilts@yahoo.com>
1874 Will Hawes C<info@whawes.co.uk>
1876 willert: Sebastian Willert <willert@cpan.org>
1878 Yuval Kogman, C<nothingmuch@woobling.org>
1882 This library is free software. You can redistribute it and/or modify it under
1883 the same terms as Perl itself.
1889 __PACKAGE__->meta->make_immutable;