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 Catalyst::Context;
13 use Devel::InnerPackage ();
14 use Module::Pluggable::Object ();
15 use Text::SimpleTable ();
16 use Path::Class::Dir ();
17 use Path::Class::File ();
18 use Tree::Simple::Visitor::FindByUID;
19 use Class::C3::Adopt::NEXT;
22 use Carp qw/croak carp shortmess/;
24 BEGIN { require 5.008004; }
26 sub comp { shift->component(@_) }
28 #I imagine that very few of these really need to be class variables. if any.
29 #maybe we should just make them attributes with a default?
30 __PACKAGE__->mk_classdata($_)
31 for qw/components arguments dispatcher engine log dispatcher_class
32 engine_class context_class request_class response_class stats_class
35 __PACKAGE__->context_class('Catalyst::Context');
36 __PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
37 __PACKAGE__->engine_class('Catalyst::Engine::CGI');
38 __PACKAGE__->request_class('Catalyst::Request');
39 __PACKAGE__->response_class('Catalyst::Response');
40 __PACKAGE__->stats_class('Catalyst::Stats');
42 # Remember to update this in Catalyst::Runtime as well!
44 our $VERSION = '5.80013';
47 my $dev_version = $VERSION =~ /_\d{2}$/;
48 *_IS_DEVELOPMENT_VERSION = sub () { $dev_version };
51 $VERSION = eval $VERSION;
57 my ( $class, @arguments ) = @_;
59 # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
61 return unless $class eq 'Catalyst';
63 my $caller = caller();
64 return if $caller eq 'main';
66 # Kill Adopt::NEXT warnings if we're a non-RC version
67 unless (_IS_DEVELOPMENT_VERSION()) {
68 Class::C3::Adopt::NEXT->unimport(qr/^Catalyst::/);
71 my $meta = Moose::Meta::Class->initialize($caller);
72 unless ( $caller->isa('Catalyst') ) {
73 my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
74 $meta->superclasses(@superclasses);
76 # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp
77 $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses);
79 unless( $meta->has_method('meta') ){
80 $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
83 $caller->arguments( [@arguments] );
87 sub _application { $_[0] }
91 Catalyst - The Elegant MVC Web Application Framework
95 See the L<Catalyst::Manual> distribution for comprehensive
96 documentation and tutorials.
98 # Install Catalyst::Devel for helpers and other development tools
99 # use the helper to create a new application
102 # add models, views, controllers
103 script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
104 script/myapp_create.pl view MyTemplate TT
105 script/myapp_create.pl controller Search
107 # built in testserver -- use -r to restart automatically on changes
108 # --help to see all available options
109 script/myapp_server.pl
111 # command line testing interface
112 script/myapp_test.pl /yada
115 use Catalyst qw/-Debug/; # include plugins here as well
117 ### In lib/MyApp/Controller/Root.pm (autocreated)
118 sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
119 my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
120 $c->stash->{template} = 'foo.tt'; # set the template
121 # lookup something from db -- stash vars are passed to TT
123 $c->model('Database::Foo')->search( { country => $args[0] } );
124 if ( $c->req->params->{bar} ) { # access GET or POST parameters
125 $c->forward( 'bar' ); # process another action
126 # do something else after forward returns
130 # The foo.tt TT template can use the stash data from the database
131 [% WHILE (item = data.next) %]
135 # called for /bar/of/soap, /bar/of/soap/10, etc.
136 sub bar : Path('/bar/of/soap') { ... }
138 # called for all actions, from the top-most controller downwards
140 my ( $self, $c ) = @_;
141 if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
142 $c->res->redirect( '/login' ); # require login
143 return 0; # abort request and go immediately to end()
145 return 1; # success; carry on to next action
148 # called after all actions are finished
150 my ( $self, $c ) = @_;
151 if ( scalar @{ $c->error } ) { ... } # handle errors
152 return if $c->res->body; # already have a response
153 $c->forward( 'MyApp::View::TT' ); # render template
156 ### in MyApp/Controller/Foo.pm
157 # called for /foo/bar
158 sub bar : Local { ... }
160 # called for /blargle
161 sub blargle : Global { ... }
163 # an index action matches /foo, but not /foo/1, etc.
164 sub index : Private { ... }
166 ### in MyApp/Controller/Foo/Bar.pm
167 # called for /foo/bar/baz
168 sub baz : Local { ... }
170 # first Root auto is called, then Foo auto, then this
171 sub auto : Private { ... }
173 # powerful regular expression paths are also possible
174 sub details : Regex('^product/(\w+)/details$') {
175 my ( $self, $c ) = @_;
176 # extract the (\w+) from the URI
177 my $product = $c->req->captures->[0];
180 See L<Catalyst::Manual::Intro> for additional information.
184 Catalyst is a modern framework for making web applications without the
185 pain usually associated with this process. This document is a reference
186 to the main Catalyst application. If you are a new user, we suggest you
187 start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
189 See L<Catalyst::Manual> for more documentation.
191 Catalyst plugins can be loaded by naming them as arguments to the "use
192 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
193 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
196 use Catalyst qw/My::Module/;
198 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
199 fully qualify the name by using a unary plus:
203 +Fully::Qualified::Plugin::Name
206 Special flags like C<-Debug> and C<-Engine> can also be specified as
207 arguments when Catalyst is loaded:
209 use Catalyst qw/-Debug My::Module/;
211 The position of plugins and flags in the chain is important, because
212 they are loaded in the order in which they appear.
214 The following flags are supported:
218 Enables debug output. You can also force this setting from the system
219 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
220 settings override the application, with <MYAPP>_DEBUG having the highest
225 Forces Catalyst to use a specific engine. Omit the
226 C<Catalyst::Engine::> prefix of the engine name, i.e.:
228 use Catalyst qw/-Engine=CGI/;
232 Forces Catalyst to use a specific home directory, e.g.:
234 use Catalyst qw[-Home=/usr/mst];
236 This can also be done in the shell environment by setting either the
237 C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
238 is replaced with the uppercased name of your application, any "::" in
239 the name will be replaced with underscores, e.g. MyApp::Web should use
240 MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
244 use Catalyst '-Log=warn,fatal,error';
246 Specifies a comma-delimited list of log levels.
250 Enables statistics collection and reporting. You can also force this setting
251 from the system environment with CATALYST_STATS or <MYAPP>_STATS. The
252 environment settings override the application, with <MYAPP>_STATS having the
257 use Catalyst qw/-Stats=1/
263 sub _comp_search_prefixes {
265 return map $c->components->{ $_ }, $c->_comp_names_search_prefixes(@_);
268 # search components given a name and some prefixes
269 sub _comp_names_search_prefixes {
270 my ( $c, $name, @prefixes ) = @_;
271 my $appclass = ref $c || $c;
272 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
273 $filter = qr/$filter/; # Compile regex now rather than once per loop
275 # map the original component name to the sub part that we will search against
276 my %eligible = map { my $n = $_; $n =~ s{^$appclass\::[^:]+::}{}; $_ => $n; }
277 grep { /$filter/ } keys %{ $c->components };
279 # undef for a name will return all
280 return keys %eligible if !defined $name;
282 my $query = ref $name ? $name : qr/^$name$/i;
283 my @result = grep { $eligible{$_} =~ m{$query} } keys %eligible;
285 return @result if @result;
287 # if we were given a regexp to search against, we're done.
290 # skip regexp fallback if configured
292 if $appclass->config->{disable_component_resolution_regex_fallback};
296 @result = grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
298 # no results? try against full names
300 @result = grep { m{$query} } keys %eligible;
303 # don't warn if we didn't find any results, it just might not exist
305 # Disgusting hack to work out correct method name
306 my $warn_for = lc $prefixes[0];
307 my $msg = "Used regexp fallback for \$c->${warn_for}('${name}'), which found '" .
308 (join '", "', @result) . "'. Relying on regexp fallback behavior for " .
309 "component resolution is unreliable and unsafe.";
310 my $short = $result[0];
311 # remove the component namespace prefix
312 $short =~ s/.*?(Model|Controller|View):://;
313 my $shortmess = Carp::shortmess('');
314 if ($shortmess =~ m#Catalyst/Plugin#) {
315 $msg .= " You probably need to set '$short' instead of '${name}' in this " .
317 } elsif ($shortmess =~ m#Catalyst/lib/(View|Controller)#) {
318 $msg .= " You probably need to set '$short' instead of '${name}' in this " .
319 "component's config";
321 $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}('${name}'), " .
322 "but if you really wanted to search, pass in a regexp as the argument " .
323 "like so: \$c->${warn_for}(qr/${name}/)";
325 $c->log->warn( "${msg}$shortmess" );
331 # Find possible names for a prefix
333 my ( $c, @prefixes ) = @_;
334 my $appclass = ref $c || $c;
336 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
338 my @names = map { s{$filter}{}; $_; }
339 $c->_comp_names_search_prefixes( undef, @prefixes );
344 # Filter a component before returning by calling ACCEPT_CONTEXT if available
345 sub _filter_component {
346 my ( $c, $comp, @args ) = @_;
348 if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) {
349 return $comp->ACCEPT_CONTEXT( $c, @args );
355 =head2 COMPONENT ACCESSORS
357 =head2 $c->controllers
359 Returns the available names which can be passed to $c->controller
365 return $c->_comp_names(qw/Controller C/);
370 Returns the available names which can be passed to $c->model
376 return $c->_comp_names(qw/Model M/);
382 Returns the available names which can be passed to $c->view
388 return $c->_comp_names(qw/View V/);
391 =head2 $c->comp($name)
393 =head2 $c->component($name)
395 Gets a component object by name. This method is not recommended,
396 unless you want to get a specific component by full
397 class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >>
398 should be used instead.
400 If C<$name> is a regexp, a list of components matched against the full
401 component name will be returned.
403 If Catalyst can't find a component by name, it will fallback to regex
404 matching by default. To disable this behaviour set
405 disable_component_resolution_regex_fallback to a true value.
407 __PACKAGE__->config( disable_component_resolution_regex_fallback => 1 );
412 my ( $c, $name, @args ) = @_;
415 my $comps = $c->components;
418 # is it the exact name?
419 return $c->_filter_component( $comps->{ $name }, @args )
420 if exists $comps->{ $name };
422 # perhaps we just omitted "MyApp"?
423 my $composed = ( ref $c || $c ) . "::${name}";
424 return $c->_filter_component( $comps->{ $composed }, @args )
425 if exists $comps->{ $composed };
427 # search all of the models, views and controllers
428 my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ );
429 return $c->_filter_component( $comp, @args ) if $comp;
432 # This is here so $c->comp( '::M::' ) works
433 my $query = ref $name ? $name : qr{$name}i;
435 my @result = grep { m{$query} } keys %{ $c->components };
436 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
439 $c->log->warn( Carp::shortmess(qq(Found results for "${name}" using regexp fallback)) );
440 $c->log->warn( 'Relying on the regexp fallback behavior for component resolution' );
441 $c->log->warn( 'is unreliable and unsafe. You have been warned' );
442 return $c->_filter_component( $result[ 0 ], @args );
445 # I would expect to return an empty list here, but that breaks back-compat
449 return sort keys %{ $c->components };
452 =head2 CLASS DATA AND HELPER CLASSES
456 Returns or takes a hashref containing the application's configuration.
458 __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
460 You can also use a C<YAML>, C<XML> or L<Config::General> config file
461 like C<myapp.conf> in your applications home directory. See
462 L<Catalyst::Plugin::ConfigLoader>.
464 =head3 Cascading configuration
466 The config method is present on all Catalyst components, and configuration
467 will be merged when an application is started. Configuration loaded with
468 L<Catalyst::Plugin::ConfigLoader> takes precedence over other configuration,
469 followed by configuration in your top level C<MyApp> class. These two
470 configurations are merged, and then configuration data whose hash key matches a
471 component name is merged with configuration for that component.
473 The configuration for a component is then passed to the C<new> method when a
474 component is constructed.
478 MyApp->config({ 'Model::Foo' => { bar => 'baz', overrides => 'me' } });
479 MyApp::Model::Foo->config({ quux => 'frob', 'overrides => 'this' });
481 will mean that C<MyApp::Model::Foo> receives the following data when
484 MyApp::Model::Foo->new({
492 around config => sub {
496 croak('Setting config after setup has been run is not allowed.')
497 if ( @_ and $c->setup_finished );
504 Returns the logging object instance. Unless it is already set, Catalyst
505 sets this up with a L<Catalyst::Log> object. To use your own log class,
506 set the logger with the C<< __PACKAGE__->log >> method prior to calling
507 C<< __PACKAGE__->setup >>.
509 __PACKAGE__->log( MyLogger->new );
514 $c->log->info( 'Now logging with my own logger!' );
516 Your log class should implement the methods described in
522 Returns 1 if debug mode is enabled, 0 otherwise.
524 You can enable debug mode in several ways:
528 =item By calling myapp_server.pl with the -d flag
530 =item With the environment variables MYAPP_DEBUG, or CATALYST_DEBUG
532 =item The -Debug option in your MyApp.pm
534 =item By declaring C<sub debug { 1 }> in your MyApp.pm.
538 Calling C<< $c->debug(1) >> has no effect.
544 =head2 $c->dispatcher
546 Returns the dispatcher instance. See L<Catalyst::Dispatcher>.
550 Returns the engine instance. See L<Catalyst::Engine>.
553 =head2 UTILITY METHODS
555 =head2 $c->path_to(@path)
557 Merges C<@path> with C<< $c->config->{home} >> and returns a
558 L<Path::Class::Dir> object. Note you can usually use this object as
559 a filename, but sometimes you will have to explicitly stringify it
560 yourself by calling the C<< ->stringify >> method.
564 $c->path_to( 'db', 'sqlite.db' );
569 my ( $c, @path ) = @_;
570 my $path = Path::Class::Dir->new( $c->config->{home}, @path );
571 if ( -d $path ) { return $path }
572 else { return Path::Class::File->new( $c->config->{home}, @path ) }
575 =head2 $c->plugin( $name, $class, @args )
577 Helper method for plugins. It creates a class data accessor/mutator and
578 loads and instantiates the given class.
580 MyApp->plugin( 'prototype', 'HTML::Prototype' );
582 $c->prototype->define_javascript_functions;
584 B<Note:> This method of adding plugins is deprecated. The ability
585 to add plugins like this B<will be removed> in a Catalyst 5.81.
586 Please do not use this functionality in new code.
591 my ( $class, $name, $plugin, @args ) = @_;
593 # See block comment in t/unit_core_plugin.t
594 $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in Catalyst 5.81/);
596 $class->_register_plugin( $plugin, 1 );
598 eval { $plugin->import };
599 $class->mk_classdata($name);
601 eval { $obj = $plugin->new(@args) };
604 Catalyst::Exception->throw( message =>
605 qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
609 $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
615 Initializes the dispatcher and engine, loads any plugins, and loads the
616 model, view, and controller components. You may also specify an array
617 of plugins to load here, if you choose to not load them in the C<use
621 MyApp->setup( qw/-Debug/ );
626 my ( $class, @arguments ) = @_;
627 croak('Running setup more than once')
628 if ( $class->setup_finished );
630 unless ( $class->isa('Catalyst') ) {
632 Catalyst::Exception->throw(
633 message => qq/'$class' does not inherit from Catalyst/ );
636 if ( $class->arguments ) {
637 @arguments = ( @arguments, @{ $class->arguments } );
643 foreach (@arguments) {
647 ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
649 elsif (/^-(\w+)=?(.*)$/) {
650 $flags->{ lc $1 } = $2;
653 push @{ $flags->{plugins} }, $_;
657 $class->setup_home( delete $flags->{home} );
659 $class->setup_log( delete $flags->{log} );
660 $class->setup_plugins( delete $flags->{plugins} );
661 $class->setup_dispatcher( delete $flags->{dispatcher} );
662 $class->setup_engine( delete $flags->{engine} );
663 $class->setup_stats( delete $flags->{stats} );
665 for my $flag ( sort keys %{$flags} ) {
667 if ( my $code = $class->can( 'setup_' . $flag ) ) {
668 &$code( $class, delete $flags->{$flag} );
671 $class->log->warn(qq/Unknown flag "$flag"/);
675 eval { require Catalyst::Devel; };
676 if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
677 $class->log->warn(<<"EOF");
678 You are running an old script!
680 Please update by running (this will overwrite existing files):
681 catalyst.pl -force -scripts $class
683 or (this will not overwrite existing files):
684 catalyst.pl -scripts $class
689 if ( $class->debug ) {
690 my @plugins = map { "$_ " . ( $_->VERSION || '' ) } $class->registered_plugins;
693 my $column_width = Catalyst::Utils::term_width() - 6;
694 my $t = Text::SimpleTable->new($column_width);
695 $t->row($_) for @plugins;
696 $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
699 my $dispatcher = $class->dispatcher;
700 my $engine = $class->engine;
701 my $home = $class->config->{home};
703 $class->log->debug(sprintf(q/Loaded dispatcher "%s"/, blessed($dispatcher)));
704 $class->log->debug(sprintf(q/Loaded engine "%s"/, blessed($engine)));
708 ? $class->log->debug(qq/Found home "$home"/)
709 : $class->log->debug(qq/Home "$home" doesn't exist/)
710 : $class->log->debug(q/Couldn't find home/);
713 # Call plugins setup, this is stupid and evil.
714 # Also screws C3 badly on 5.10, hack to avoid.
716 no warnings qw/redefine/;
717 local *setup = sub { };
718 $class->setup unless $Catalyst::__AM_RESTARTING;
721 # Initialize our data structure
722 $class->components( {} );
724 $class->setup_components;
726 if ( $class->debug ) {
727 my $column_width = Catalyst::Utils::term_width() - 8 - 9;
728 my $t = Text::SimpleTable->new( [ $column_width, 'Class' ], [ 8, 'Type' ] );
729 for my $comp ( sort keys %{ $class->components } ) {
730 my $type = ref $class->components->{$comp} ? 'instance' : 'class';
731 $t->row( $comp, $type );
733 $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
734 if ( keys %{ $class->components } );
737 # Add our self to components, since we are also a component
738 if( $class->isa('Catalyst::Controller') ){
739 $class->components->{$class} = $class;
742 $class->setup_actions;
744 if ( $class->debug ) {
745 my $name = $class->config->{name} || 'Application';
746 $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
749 # Make sure that the application class becomes immutable at this point,
750 B::Hooks::EndOfScope::on_scope_end {
752 my $meta = Class::MOP::get_metaclass_by_name($class);
755 && ! { $meta->immutable_options }->{replace_constructor}
757 $class->isa('Class::Accessor::Fast')
758 || $class->isa('Class::Accessor')
761 warn "You made your application class ($class) immutable, "
762 . "but did not inline the\nconstructor. "
763 . "This will break catalyst, as your app \@ISA "
764 . "Class::Accessor(::Fast)?\nPlease pass "
765 . "(replace_constructor => 1)\nwhen making your class immutable.\n";
767 $meta->make_immutable(
768 replace_constructor => 1,
769 ) unless $meta->is_immutable;
772 $class->setup_finalize;
773 # Should be the last thing we do so that user things hooking
774 # setup_finalize can log..
775 $class->log->_flush() if $class->log->can('_flush');
776 return 1; # Explicit return true as people have __PACKAGE__->setup as the last thing in their class. HATE.
780 =head2 $app->setup_finalize
782 A hook to attach modifiers to.
783 Using C<< after setup => sub{}; >> doesn't work, because of quirky things done for plugin setup.
784 Also better than C< setup_finished(); >, as that is a getter method.
790 ## do stuff, i.e., determine a primary key column for sessions stored in a DB
792 $app->next::method(@_);
801 $class->setup_finished(1);
804 =head2 $c->welcome_message
806 Returns the Catalyst welcome HTML page.
810 sub welcome_message {
812 my $name = $c->config->{name};
813 my $logo = $c->uri_for('/static/images/catalyst_logo.png');
814 my $prefix = Catalyst::Utils::appprefix( ref $c );
815 $c->response->content_type('text/html; charset=utf-8');
817 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
818 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
819 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
821 <meta http-equiv="Content-Language" content="en" />
822 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
823 <title>$name on Catalyst $VERSION</title>
824 <style type="text/css">
827 background-color: #eee;
836 background-color: #ccc;
837 border: 1px solid #aaa;
842 font-family: verdana, tahoma, sans-serif;
845 font-family: verdana, tahoma, sans-serif;
848 text-decoration: none;
850 border-bottom: 1px dotted #bbb;
852 :link:hover, :visited:hover {
865 background-color: #fff;
866 border: 1px solid #aaa;
892 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
897 <img src="$logo" alt="Catalyst Logo" />
899 <p>Welcome to the world of Catalyst.
900 This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
901 framework will make web development something you had
902 never expected it to be: Fun, rewarding, and quick.</p>
903 <h2>What to do now?</h2>
904 <p>That really depends on what <b>you</b> want to do.
905 We do, however, provide you with a few starting points.</p>
906 <p>If you want to jump right into web development with Catalyst
907 you might want to start with a tutorial.</p>
908 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
910 <p>Afterwards you can go on to check out a more complete look at our features.</p>
912 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
913 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
915 <h2>What to do next?</h2>
916 <p>Next it's time to write an actual application. Use the
917 helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&mode=all">controllers</a>,
918 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&mode=all">models</a>, and
919 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&mode=all">views</a>;
920 they can save you a lot of work.</p>
921 <pre><code>script/${prefix}_create.pl -help</code></pre>
922 <p>Also, be sure to check out the vast and growing
923 collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
924 you are likely to find what you need there.
928 <p>Catalyst has a very active community. Here are the main places to
929 get in touch with us.</p>
932 <a href="http://dev.catalyst.perl.org">Wiki</a>
935 <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a>
938 <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
941 <h2>In conclusion</h2>
942 <p>The Catalyst team hopes you will enjoy using Catalyst as much
943 as we enjoyed making it. Please contact us if you have ideas
944 for improvement or other feedback.</p>
952 =head1 INTERNAL METHODS
954 These methods are not meant to be used by end users.
956 =head2 $c->components
958 Returns a hash of components.
960 =head2 $c->context_class
962 Returns or sets the context class.
964 =head2 $c->dispatcher_class
966 Returns or sets the dispatcher class.
968 =head2 $c->engine_class
970 Returns or sets the engine class.
972 =head2 $c->handle_request( $class, @arguments )
974 Called to handle each HTTP request.
979 my ( $class, @arguments ) = @_;
981 # Always expect worst case!
985 my $secs = time - $START || 1;
986 my $av = sprintf '%.3f', $COUNT / $secs;
987 my $time = localtime time;
988 $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
991 my $c = $class->prepare(@arguments);
993 $status = $c->finalize;
996 if ( my $error = $@ ) {
998 $class->log->error(qq/Caught exception in engine "$error"/);
1003 if(my $coderef = $class->log->can('_flush')){
1004 $class->log->$coderef();
1009 =head2 $c->prepare( @arguments )
1011 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1017 my ( $class, @arguments ) = @_;
1020 # After the app/ctxt split, this should become an attribute based on something passed
1021 # into the application.
1022 $class->context_class( ref $class || $class ) unless $class->context_class;
1024 my $app = $class->new({});
1025 my $c = $class->context_class->new( application => $app );
1027 # For on-demand data
1028 $c->request->_context($c);
1029 $c->response->_context($c);
1031 #surely this is not the most efficient way to do things...
1032 $c->stats($class->stats_class->new)->enable($c->use_stats);
1034 $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
1037 #XXX reuse coderef from can
1038 # Allow engine to direct the prepare flow (for POE)
1039 if ( $c->engine->can('prepare') ) {
1040 $c->engine->prepare( $c, @arguments );
1043 $c->prepare_request(@arguments);
1044 $c->prepare_connection;
1045 $c->prepare_query_parameters;
1046 $c->prepare_headers;
1047 $c->prepare_cookies;
1050 # Prepare the body for reading, either by prepare_body
1051 # or the user, if they are using $c->read
1054 # Parse the body unless the user wants it on-demand
1055 unless ( $app->config->{parse_on_demand} ) {
1060 my $method = $c->req->method || '';
1061 my $path = $c->req->path;
1062 $path = '/' unless length $path;
1063 my $address = $c->req->address || '';
1065 $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1073 =head2 $c->request_class
1075 Returns or sets the request class.
1077 =head2 $c->response_class
1079 Returns or sets the response class.
1087 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1089 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1091 Sets an action in a given namespace.
1095 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1097 =head2 $c->setup_actions($component)
1099 Sets up actions for a component.
1103 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1105 =head2 $c->setup_components
1107 This method is called internally to set up the application's components.
1109 It finds modules by calling the L<locate_components> method, expands them to
1110 package names with the L<expand_component_module> method, and then installs
1111 each component into the application.
1113 The C<setup_components> config option is passed to both of the above methods.
1115 Installation of each component is performed by the L<setup_component> method,
1120 sub setup_components {
1123 my $config = $class->config->{ setup_components };
1125 my @comps = sort { length $a <=> length $b }
1126 $class->locate_components($config);
1127 my %comps = map { $_ => 1 } @comps;
1129 my $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @comps;
1130 $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
1131 qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
1132 ) if $deprecatedcatalyst_component_names;
1134 for my $component ( @comps ) {
1136 # We pass ignore_loaded here so that overlay files for (e.g.)
1137 # Model::DBI::Schema sub-classes are loaded - if it's in @comps
1138 # we know M::P::O found a file on disk so this is safe
1140 Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
1142 # Needs to be done as soon as the component is loaded, as loading a sub-component
1143 # (next time round the loop) can cause us to get the wrong metaclass..
1144 $class->_controller_init_base_classes($component);
1147 for my $component (@comps) {
1148 $class->components->{ $component } = $class->setup_component($component);
1149 for my $component ($class->expand_component_module( $component, $config )) {
1150 next if $comps{$component};
1151 $class->_controller_init_base_classes($component); # Also cover inner packages
1152 $class->components->{ $component } = $class->setup_component($component);
1157 =head2 $c->locate_components( $setup_component_config )
1159 This method is meant to provide a list of component modules that should be
1160 setup for the application. By default, it will use L<Module::Pluggable>.
1162 Specify a C<setup_components> config option to pass additional options directly
1163 to L<Module::Pluggable>. To add additional search paths, specify a key named
1164 C<search_extra> as an array reference. Items in the array beginning with C<::>
1165 will have the application class name prepended to them.
1169 sub locate_components {
1173 my @paths = qw( ::Controller ::C ::Model ::M ::View ::V );
1174 my $extra = delete $config->{ search_extra } || [];
1176 push @paths, @$extra;
1178 my $locator = Module::Pluggable::Object->new(
1179 search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
1183 my @comps = $locator->plugins;
1188 =head2 $c->expand_component_module( $component, $setup_component_config )
1190 Components found by C<locate_components> will be passed to this method, which
1191 is expected to return a list of component (package) names to be set up.
1195 sub expand_component_module {
1196 my ($class, $module) = @_;
1197 return Devel::InnerPackage::list_packages( $module );
1200 =head2 $c->setup_component
1204 # FIXME - Ugly, ugly hack to ensure the we force initialize non-moose base classes
1205 # nearest to Catalyst::Controller first, no matter what order stuff happens
1206 # to be loaded. There are TODO tests in Moose for this, see
1207 # f2391d17574eff81d911b97be15ea51080500003
1208 sub _controller_init_base_classes {
1209 my ($app_class, $component) = @_;
1210 return unless $component->isa('Catalyst::Controller');
1211 foreach my $class ( reverse @{ mro::get_linear_isa($component) } ) {
1212 Moose::Meta::Class->initialize( $class )
1213 unless find_meta($class);
1217 sub setup_component {
1218 my( $class, $component ) = @_;
1220 unless ( $component->can( 'COMPONENT' ) ) {
1224 my $suffix = Catalyst::Utils::class2classsuffix( $component );
1225 my $config = $class->config->{ $suffix } || {};
1226 # Stash catalyst_component_name in the config here, so that custom COMPONENT
1227 # methods also pass it. local to avoid pointlessly shitting in config
1228 # for the debug screen, as $component is already the key name.
1229 local $config->{catalyst_component_name} = $component;
1231 my $instance = eval { $component->COMPONENT( $class, $config ); };
1233 if ( my $error = $@ ) {
1235 Catalyst::Exception->throw(
1236 message => qq/Couldn't instantiate component "$component", "$error"/
1240 unless (blessed $instance) {
1241 my $metaclass = Moose::Util::find_meta($component);
1242 my $method_meta = $metaclass->find_method_by_name('COMPONENT');
1243 my $component_method_from = $method_meta->associated_metaclass->name;
1244 my $value = defined($instance) ? $instance : 'undef';
1245 Catalyst::Exception->throw(
1247 qq/Couldn't instantiate component "$component", COMPONENT() method (from $component_method_from) didn't return an object-like value (value was $value)./
1253 =head2 $c->setup_dispatcher
1259 sub setup_dispatcher {
1260 my ( $class, $dispatcher ) = @_;
1263 $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
1266 if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
1267 $dispatcher = 'Catalyst::Dispatcher::' . $env;
1270 unless ($dispatcher) {
1271 $dispatcher = $class->dispatcher_class;
1274 Class::MOP::load_class($dispatcher);
1276 # dispatcher instance
1277 $class->dispatcher( $dispatcher->new );
1280 =head2 $c->setup_engine
1287 my ( $class, $engine ) = @_;
1290 $engine = 'Catalyst::Engine::' . $engine;
1293 if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
1294 $engine = 'Catalyst::Engine::' . $env;
1297 if ( $ENV{MOD_PERL} ) {
1298 my $meta = Class::MOP::get_metaclass_by_name($class);
1300 # create the apache method
1301 $meta->add_method('apache' => sub { shift->engine->apache });
1303 my ( $software, $version ) =
1304 $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
1307 $version =~ s/(\.[^.]+)\./$1/g;
1309 if ( $software eq 'mod_perl' ) {
1313 if ( $version >= 1.99922 ) {
1314 $engine = 'Catalyst::Engine::Apache2::MP20';
1317 elsif ( $version >= 1.9901 ) {
1318 $engine = 'Catalyst::Engine::Apache2::MP19';
1321 elsif ( $version >= 1.24 ) {
1322 $engine = 'Catalyst::Engine::Apache::MP13';
1326 Catalyst::Exception->throw( message =>
1327 qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
1332 # install the correct mod_perl handler
1333 if ( $version >= 1.9901 ) {
1334 *handler = sub : method {
1335 shift->handle_request(@_);
1339 *handler = sub ($$) { shift->handle_request(@_) };
1344 elsif ( $software eq 'Zeus-Perl' ) {
1345 $engine = 'Catalyst::Engine::Zeus';
1349 Catalyst::Exception->throw(
1350 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
1355 $engine = $class->engine_class;
1358 Class::MOP::load_class($engine);
1360 # check for old engines that are no longer compatible
1362 if ( $engine->isa('Catalyst::Engine::Apache')
1363 && !Catalyst::Engine::Apache->VERSION )
1368 elsif ( $engine->isa('Catalyst::Engine::Server::Base')
1369 && Catalyst::Engine::Server->VERSION le '0.02' )
1374 elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
1375 && $engine->VERSION eq '0.01' )
1380 elsif ($engine->isa('Catalyst::Engine::Zeus')
1381 && $engine->VERSION eq '0.01' )
1387 Catalyst::Exception->throw( message =>
1388 qq/Engine "$engine" is not supported by this version of Catalyst/
1393 $class->engine( $engine->new );
1396 =head2 $c->setup_home
1398 Sets up the home directory.
1403 my ( $class, $home ) = @_;
1405 if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
1409 $home ||= Catalyst::Utils::home($class);
1412 #I remember recently being scolded for assigning config values like this
1413 $class->config->{home} ||= $home;
1414 $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
1418 =head2 $c->setup_log
1420 Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and
1421 passing it to C<log()>. Pass in a comma-delimited list of levels to set the
1424 This method also installs a C<debug> method that returns a true value into the
1425 catalyst subclass if the "debug" level is passed in the comma-delimited list,
1426 or if the C<$CATALYST_DEBUG> environment variable is set to a true value.
1428 Note that if the log has already been setup, by either a previous call to
1429 C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>,
1430 that this method won't actually set up the log object.
1435 my ( $class, $levels ) = @_;
1438 $levels =~ s/^\s+//;
1439 $levels =~ s/\s+$//;
1440 my %levels = map { $_ => 1 } split /\s*,\s*/, $levels;
1442 my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
1443 if ( defined $env_debug ) {
1444 $levels{debug} = 1 if $env_debug; # Ugly!
1445 delete($levels{debug}) unless $env_debug;
1448 unless ( $class->log ) {
1449 $class->log( Catalyst::Log->new(keys %levels) );
1452 if ( $levels{debug} ) {
1453 Class::MOP::get_metaclass_by_name($class)->add_method('debug' => sub { 1 });
1454 $class->log->debug('Debug messages enabled');
1458 =head2 $c->setup_plugins
1464 =head2 $c->setup_stats
1466 Sets up timing statistics class.
1471 my ( $class, $stats ) = @_;
1473 Catalyst::Utils::ensure_class_loaded($class->stats_class);
1475 my $env = Catalyst::Utils::env_value( $class, 'STATS' );
1476 if ( defined($env) ? $env : ($stats || $class->debug ) ) {
1477 Class::MOP::get_metaclass_by_name($class)->add_method('use_stats' => sub { 1 });
1478 $class->log->debug('Statistics enabled');
1483 =head2 $c->registered_plugins
1485 Returns a sorted list of the plugins which have either been stated in the
1486 import list or which have been added via C<< MyApp->plugin(@args); >>.
1488 If passed a given plugin name, it will report a boolean value indicating
1489 whether or not that plugin is loaded. A fully qualified name is required if
1490 the plugin name does not begin with C<Catalyst::Plugin::>.
1492 if ($c->registered_plugins('Some::Plugin')) {
1500 sub registered_plugins {
1502 return sort keys %{ $proto->_plugins } unless @_;
1504 return 1 if exists $proto->_plugins->{$plugin};
1505 return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
1508 sub _register_plugin {
1509 my ( $proto, $plugin, $instant ) = @_;
1510 my $class = ref $proto || $proto;
1512 Class::MOP::load_class( $plugin );
1514 $proto->_plugins->{$plugin} = 1;
1517 if ( my $meta = Class::MOP::get_metaclass_by_name($class) ) {
1518 my @superclasses = ($plugin, $meta->superclasses );
1519 $meta->superclasses(@superclasses);
1521 unshift @{"$class\::ISA"}, $plugin;
1528 my ( $class, $plugins ) = @_;
1530 $class->_plugins( {} ) unless $class->_plugins;
1533 my @plugins = Catalyst::Utils::resolve_namespace($class . '::Plugin', 'Catalyst::Plugin', @$plugins);
1535 for my $plugin ( reverse @plugins ) {
1536 Class::MOP::load_class($plugin);
1537 my $meta = find_meta($plugin);
1538 next if $meta && $meta->isa('Moose::Meta::Role');
1540 $class->_register_plugin($plugin);
1545 grep { $_ && blessed($_) && $_->isa('Moose::Meta::Role') }
1546 map { find_meta($_) }
1549 Moose::Util::apply_all_roles(
1555 =head2 $c->stats_class
1557 Returns or sets the stats (timing statistics) class.
1559 =head2 $c->use_stats
1561 Returns 1 when stats collection is enabled. Stats collection is enabled
1562 when the -Stats options is set, debug is on or when the <MYAPP>_STATS
1563 environment variable is set.
1565 Note that this is a static method, not an accessor and should be overridden
1566 by declaring C<sub use_stats { 1 }> in your MyApp.pm, not by calling C<< $c->use_stats(1) >>.
1574 Returns the Catalyst version number. Mostly useful for "powered by"
1575 messages in template systems.
1579 sub version { return $Catalyst::VERSION }
1581 =head1 CONFIGURATION
1583 There are a number of 'base' config variables which can be set:
1589 C<default_model> - The default model picked if you say C<< $c->model >>. See L</$c->model($name)>.
1593 C<default_view> - The default view to be rendered or returned when C<< $c->view >>. See L</$c->view($name)>.
1598 C<disable_component_resolution_regex_fallback> - Turns
1599 off the deprecated component resolution functionality so
1600 that if any of the component methods (e.g. C<< $c->controller('Foo') >>)
1601 are called then regex search will not be attempted on string values and
1602 instead C<undef> will be returned.
1606 C<home> - The application home directory. In an uninstalled application,
1607 this is the top level application directory. In an installed application,
1608 this will be the directory containing C<< MyApp.pm >>.
1612 C<ignore_frontend_proxy> - See L</PROXY SUPPORT>
1616 C<name> - The name of the application in debug messages and the debug and
1621 C<parse_on_demand> - The request body (for example file uploads) will not be parsed
1622 until it is accessed. This allows you to (for example) check authentication (and reject
1623 the upload) before actually recieving all the data. See L</ON-DEMAND PARSER>
1627 C<root> - The root directory for templates. Usually this is just a
1628 subdirectory of the home directory, but you can set it to change the
1629 templates to a different directory.
1633 C<search_extra> - Array reference passed to Module::Pluggable to for additional
1634 namespaces from which components will be loaded (and constructed and stored in
1635 C<< $c->components >>).
1639 C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >>
1640 to be shown in hit debug tables in the test server.
1644 C<using_frontend_proxy> - See L</PROXY SUPPORT>.
1648 =head1 INTERNAL ACTIONS
1650 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
1651 C<_ACTION>, and C<_END>. These are by default not shown in the private
1652 action table, but you can make them visible with a config parameter.
1654 MyApp->config(show_internal_actions => 1);
1656 =head1 ON-DEMAND PARSER
1658 The request body is usually parsed at the beginning of a request,
1659 but if you want to handle input yourself, you can enable on-demand
1660 parsing with a config parameter.
1662 MyApp->config(parse_on_demand => 1);
1664 =head1 PROXY SUPPORT
1666 Many production servers operate using the common double-server approach,
1667 with a lightweight frontend web server passing requests to a larger
1668 backend server. An application running on the backend server must deal
1669 with two problems: the remote user always appears to be C<127.0.0.1> and
1670 the server's hostname will appear to be C<localhost> regardless of the
1671 virtual host that the user connected through.
1673 Catalyst will automatically detect this situation when you are running
1674 the frontend and backend servers on the same machine. The following
1675 changes are made to the request.
1677 $c->req->address is set to the user's real IP address, as read from
1678 the HTTP X-Forwarded-For header.
1680 The host value for $c->req->base and $c->req->uri is set to the real
1681 host, as read from the HTTP X-Forwarded-Host header.
1683 Additionally, you may be running your backend application on an insecure
1684 connection (port 80) while your frontend proxy is running under SSL. If there
1685 is a discrepancy in the ports, use the HTTP header C<X-Forwarded-Port> to
1686 tell Catalyst what port the frontend listens on. This will allow all URIs to
1687 be created properly.
1689 In the case of passing in:
1691 X-Forwarded-Port: 443
1693 All calls to C<uri_for> will result in an https link, as is expected.
1695 Obviously, your web server must support these headers for this to work.
1697 In a more complex server farm environment where you may have your
1698 frontend proxy server(s) on different machines, you will need to set a
1699 configuration option to tell Catalyst to read the proxied data from the
1702 MyApp->config(using_frontend_proxy => 1);
1704 If you do not wish to use the proxy support at all, you may set:
1706 MyApp->config(ignore_frontend_proxy => 1);
1708 =head1 THREAD SAFETY
1710 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
1711 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
1712 believe the Catalyst core to be thread-safe.
1714 If you plan to operate in a threaded environment, remember that all other
1715 modules you are using must also be thread-safe. Some modules, most notably
1716 L<DBD::SQLite>, are not thread-safe.
1722 Join #catalyst on irc.perl.org.
1726 http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
1727 http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
1731 http://catalyst.perl.org
1735 http://dev.catalyst.perl.org
1739 =head2 L<Task::Catalyst> - All you need to start with Catalyst
1741 =head2 L<Catalyst::Manual> - The Catalyst Manual
1743 =head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components
1745 =head2 L<Catalyst::Engine> - Core engine
1747 =head2 L<Catalyst::Log> - Log class.
1749 =head2 L<Catalyst::Request> - Request object
1751 =head2 L<Catalyst::Response> - Response object
1753 =head2 L<Catalyst::Test> - The test suite.
1755 =head1 PROJECT FOUNDER
1757 sri: Sebastian Riedel <sri@cpan.org>
1763 acme: Leon Brocard <leon@astray.com>
1765 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
1769 Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
1773 andyg: Andy Grundman <andy@hybridized.org>
1775 audreyt: Audrey Tang
1777 bricas: Brian Cassidy <bricas@cpan.org>
1779 Caelum: Rafael Kitover <rkitover@io.com>
1781 chansen: Christian Hansen
1783 chicks: Christopher Hicks
1785 Chisel Wright C<pause@herlpacker.co.uk>
1787 Danijel Milicevic C<me@danijel.de>
1789 David Kamholz E<lt>dkamholz@cpan.orgE<gt>
1791 David Naughton, C<naughton@umn.edu>
1795 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
1799 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
1801 esskar: Sascha Kiefer
1803 fireartist: Carl Franks <cfranks@cpan.org>
1805 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
1807 gabb: Danijel Milicevic
1811 Gavin Henry C<ghenry@perl.me.uk>
1815 groditi: Guillermo Roditi <groditi@gmail.com>
1817 hobbs: Andrew Rodland <andrew@cleverdomain.org>
1819 ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
1821 jcamacho: Juan Camacho
1823 jester: Jesse Sheidlower C<jester@panix.com>
1825 jhannah: Jay Hannah <jay@jays.net>
1831 jon: Jon Schutz <jjschutz@cpan.org>
1833 Jonathan Rockway C<< <jrockway@cpan.org> >>
1835 Kieren Diment C<kd@totaldatasolution.com>
1837 konobi: Scott McWhirter <konobi@cpan.org>
1839 marcus: Marcus Ramberg <mramberg@cpan.org>
1841 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
1843 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
1847 naughton: David Naughton
1849 ningu: David Kamholz <dkamholz@cpan.org>
1851 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
1853 numa: Dan Sully <daniel@cpan.org>
1857 omega: Andreas Marienborg
1859 Oleg Kostyuk <cub.uanic@gmail.com>
1861 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
1863 rafl: Florian Ragwitz <rafl@debian.org>
1865 random: Roland Lammel <lammel@cpan.org>
1867 Robert Sedlacek C<< <rs@474.at> >>
1871 t0m: Tomas Doran <bobtfish@bobtfish.net>
1875 Viljo Marrandi C<vilts@yahoo.com>
1877 Will Hawes C<info@whawes.co.uk>
1879 willert: Sebastian Willert <willert@cpan.org>
1881 Yuval Kogman, C<nothingmuch@woobling.org>
1885 This library is free software. You can redistribute it and/or modify it under
1886 the same terms as Perl itself.
1892 __PACKAGE__->meta->make_immutable;