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;
55 our $DETACH = Catalyst::Exception::Detach->new;
56 our $GO = Catalyst::Exception::Go->new;
59 my ( $class, @arguments ) = @_;
61 # We have to limit $class to Catalyst to avoid pushing Catalyst upon every
63 return unless $class eq 'Catalyst';
65 my $caller = caller();
66 return if $caller eq 'main';
68 # Kill Adopt::NEXT warnings if we're a non-RC version
69 unless (_IS_DEVELOPMENT_VERSION()) {
70 Class::C3::Adopt::NEXT->unimport(qr/^Catalyst::/);
73 my $meta = Moose::Meta::Class->initialize($caller);
74 unless ( $caller->isa('Catalyst') ) {
75 my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
76 $meta->superclasses(@superclasses);
78 # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp
79 $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses);
81 unless( $meta->has_method('meta') ){
82 $meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
85 $caller->arguments( [@arguments] );
89 sub _application { $_[0] }
93 Catalyst - The Elegant MVC Web Application Framework
97 See the L<Catalyst::Manual> distribution for comprehensive
98 documentation and tutorials.
100 # Install Catalyst::Devel for helpers and other development tools
101 # use the helper to create a new application
104 # add models, views, controllers
105 script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
106 script/myapp_create.pl view MyTemplate TT
107 script/myapp_create.pl controller Search
109 # built in testserver -- use -r to restart automatically on changes
110 # --help to see all available options
111 script/myapp_server.pl
113 # command line testing interface
114 script/myapp_test.pl /yada
117 use Catalyst qw/-Debug/; # include plugins here as well
119 ### In lib/MyApp/Controller/Root.pm (autocreated)
120 sub foo : Global { # called for /foo, /foo/1, /foo/1/2, etc.
121 my ( $self, $c, @args ) = @_; # args are qw/1 2/ for /foo/1/2
122 $c->stash->{template} = 'foo.tt'; # set the template
123 # lookup something from db -- stash vars are passed to TT
125 $c->model('Database::Foo')->search( { country => $args[0] } );
126 if ( $c->req->params->{bar} ) { # access GET or POST parameters
127 $c->forward( 'bar' ); # process another action
128 # do something else after forward returns
132 # The foo.tt TT template can use the stash data from the database
133 [% WHILE (item = data.next) %]
137 # called for /bar/of/soap, /bar/of/soap/10, etc.
138 sub bar : Path('/bar/of/soap') { ... }
140 # called for all actions, from the top-most controller downwards
142 my ( $self, $c ) = @_;
143 if ( !$c->user_exists ) { # Catalyst::Plugin::Authentication
144 $c->res->redirect( '/login' ); # require login
145 return 0; # abort request and go immediately to end()
147 return 1; # success; carry on to next action
150 # called after all actions are finished
152 my ( $self, $c ) = @_;
153 if ( scalar @{ $c->error } ) { ... } # handle errors
154 return if $c->res->body; # already have a response
155 $c->forward( 'MyApp::View::TT' ); # render template
158 ### in MyApp/Controller/Foo.pm
159 # called for /foo/bar
160 sub bar : Local { ... }
162 # called for /blargle
163 sub blargle : Global { ... }
165 # an index action matches /foo, but not /foo/1, etc.
166 sub index : Private { ... }
168 ### in MyApp/Controller/Foo/Bar.pm
169 # called for /foo/bar/baz
170 sub baz : Local { ... }
172 # first Root auto is called, then Foo auto, then this
173 sub auto : Private { ... }
175 # powerful regular expression paths are also possible
176 sub details : Regex('^product/(\w+)/details$') {
177 my ( $self, $c ) = @_;
178 # extract the (\w+) from the URI
179 my $product = $c->req->captures->[0];
182 See L<Catalyst::Manual::Intro> for additional information.
186 Catalyst is a modern framework for making web applications without the
187 pain usually associated with this process. This document is a reference
188 to the main Catalyst application. If you are a new user, we suggest you
189 start with L<Catalyst::Manual::Tutorial> or L<Catalyst::Manual::Intro>.
191 See L<Catalyst::Manual> for more documentation.
193 Catalyst plugins can be loaded by naming them as arguments to the "use
194 Catalyst" statement. Omit the C<Catalyst::Plugin::> prefix from the
195 plugin name, i.e., C<Catalyst::Plugin::My::Module> becomes
198 use Catalyst qw/My::Module/;
200 If your plugin starts with a name other than C<Catalyst::Plugin::>, you can
201 fully qualify the name by using a unary plus:
205 +Fully::Qualified::Plugin::Name
208 Special flags like C<-Debug> and C<-Engine> can also be specified as
209 arguments when Catalyst is loaded:
211 use Catalyst qw/-Debug My::Module/;
213 The position of plugins and flags in the chain is important, because
214 they are loaded in the order in which they appear.
216 The following flags are supported:
220 Enables debug output. You can also force this setting from the system
221 environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
222 settings override the application, with <MYAPP>_DEBUG having the highest
227 Forces Catalyst to use a specific engine. Omit the
228 C<Catalyst::Engine::> prefix of the engine name, i.e.:
230 use Catalyst qw/-Engine=CGI/;
234 Forces Catalyst to use a specific home directory, e.g.:
236 use Catalyst qw[-Home=/usr/mst];
238 This can also be done in the shell environment by setting either the
239 C<CATALYST_HOME> environment variable or C<MYAPP_HOME>; where C<MYAPP>
240 is replaced with the uppercased name of your application, any "::" in
241 the name will be replaced with underscores, e.g. MyApp::Web should use
242 MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
246 use Catalyst '-Log=warn,fatal,error';
248 Specifies a comma-delimited list of log levels.
252 Enables statistics collection and reporting. You can also force this setting
253 from the system environment with CATALYST_STATS or <MYAPP>_STATS. The
254 environment settings override the application, with <MYAPP>_STATS having the
259 use Catalyst qw/-Stats=1/
265 =head2 $c->controller($name)
267 Gets a L<Catalyst::Controller> instance by name.
269 $c->controller('Foo')->do_stuff;
271 If the name is omitted, will return the controller for the dispatched
274 If you want to search for controllers, pass in a regexp as the argument.
276 # find all controllers that start with Foo
277 my @foo_controllers = $c->controller(qr{^Foo});
283 my ( $c, $name, @args ) = @_;
286 my @result = $c->_comp_search_prefixes( $name, qw/Controller C/ );
287 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
288 return $c->_filter_component( $result[ 0 ], @args );
291 return $c->component( $c->action->class );
294 sub _comp_search_prefixes {
296 return map $c->components->{ $_ }, $c->_comp_names_search_prefixes(@_);
299 # search components given a name and some prefixes
300 sub _comp_names_search_prefixes {
301 my ( $c, $name, @prefixes ) = @_;
302 my $appclass = ref $c || $c;
303 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
304 $filter = qr/$filter/; # Compile regex now rather than once per loop
306 # map the original component name to the sub part that we will search against
307 my %eligible = map { my $n = $_; $n =~ s{^$appclass\::[^:]+::}{}; $_ => $n; }
308 grep { /$filter/ } keys %{ $c->components };
310 # undef for a name will return all
311 return keys %eligible if !defined $name;
313 my $query = ref $name ? $name : qr/^$name$/i;
314 my @result = grep { $eligible{$_} =~ m{$query} } keys %eligible;
316 return @result if @result;
318 # if we were given a regexp to search against, we're done.
321 # skip regexp fallback if configured
323 if $appclass->config->{disable_component_resolution_regex_fallback};
327 @result = grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
329 # no results? try against full names
331 @result = grep { m{$query} } keys %eligible;
334 # don't warn if we didn't find any results, it just might not exist
336 # Disgusting hack to work out correct method name
337 my $warn_for = lc $prefixes[0];
338 my $msg = "Used regexp fallback for \$c->${warn_for}('${name}'), which found '" .
339 (join '", "', @result) . "'. Relying on regexp fallback behavior for " .
340 "component resolution is unreliable and unsafe.";
341 my $short = $result[0];
342 # remove the component namespace prefix
343 $short =~ s/.*?(Model|Controller|View):://;
344 my $shortmess = Carp::shortmess('');
345 if ($shortmess =~ m#Catalyst/Plugin#) {
346 $msg .= " You probably need to set '$short' instead of '${name}' in this " .
348 } elsif ($shortmess =~ m#Catalyst/lib/(View|Controller)#) {
349 $msg .= " You probably need to set '$short' instead of '${name}' in this " .
350 "component's config";
352 $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}('${name}'), " .
353 "but if you really wanted to search, pass in a regexp as the argument " .
354 "like so: \$c->${warn_for}(qr/${name}/)";
356 $c->log->warn( "${msg}$shortmess" );
362 # Find possible names for a prefix
364 my ( $c, @prefixes ) = @_;
365 my $appclass = ref $c || $c;
367 my $filter = "^${appclass}::(" . join( '|', @prefixes ) . ')::';
369 my @names = map { s{$filter}{}; $_; }
370 $c->_comp_names_search_prefixes( undef, @prefixes );
375 # Filter a component before returning by calling ACCEPT_CONTEXT if available
376 sub _filter_component {
377 my ( $c, $comp, @args ) = @_;
379 if ( eval { $comp->can('ACCEPT_CONTEXT'); } ) {
380 return $comp->ACCEPT_CONTEXT( $c, @args );
386 =head2 COMPONENT ACCESSORS
388 =head2 $c->controllers
390 Returns the available names which can be passed to $c->controller
396 return $c->_comp_names(qw/Controller C/);
401 Returns the available names which can be passed to $c->model
407 return $c->_comp_names(qw/Model M/);
413 Returns the available names which can be passed to $c->view
419 return $c->_comp_names(qw/View V/);
422 =head2 $c->comp($name)
424 =head2 $c->component($name)
426 Gets a component object by name. This method is not recommended,
427 unless you want to get a specific component by full
428 class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >>
429 should be used instead.
431 If C<$name> is a regexp, a list of components matched against the full
432 component name will be returned.
434 If Catalyst can't find a component by name, it will fallback to regex
435 matching by default. To disable this behaviour set
436 disable_component_resolution_regex_fallback to a true value.
438 __PACKAGE__->config( disable_component_resolution_regex_fallback => 1 );
443 my ( $c, $name, @args ) = @_;
446 my $comps = $c->components;
449 # is it the exact name?
450 return $c->_filter_component( $comps->{ $name }, @args )
451 if exists $comps->{ $name };
453 # perhaps we just omitted "MyApp"?
454 my $composed = ( ref $c || $c ) . "::${name}";
455 return $c->_filter_component( $comps->{ $composed }, @args )
456 if exists $comps->{ $composed };
458 # search all of the models, views and controllers
459 my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ );
460 return $c->_filter_component( $comp, @args ) if $comp;
463 # This is here so $c->comp( '::M::' ) works
464 my $query = ref $name ? $name : qr{$name}i;
466 my @result = grep { m{$query} } keys %{ $c->components };
467 return map { $c->_filter_component( $_, @args ) } @result if ref $name;
470 $c->log->warn( Carp::shortmess(qq(Found results for "${name}" using regexp fallback)) );
471 $c->log->warn( 'Relying on the regexp fallback behavior for component resolution' );
472 $c->log->warn( 'is unreliable and unsafe. You have been warned' );
473 return $c->_filter_component( $result[ 0 ], @args );
476 # I would expect to return an empty list here, but that breaks back-compat
480 return sort keys %{ $c->components };
483 =head2 CLASS DATA AND HELPER CLASSES
487 Returns or takes a hashref containing the application's configuration.
489 __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
491 You can also use a C<YAML>, C<XML> or L<Config::General> config file
492 like C<myapp.conf> in your applications home directory. See
493 L<Catalyst::Plugin::ConfigLoader>.
495 =head3 Cascading configuration
497 The config method is present on all Catalyst components, and configuration
498 will be merged when an application is started. Configuration loaded with
499 L<Catalyst::Plugin::ConfigLoader> takes precedence over other configuration,
500 followed by configuration in your top level C<MyApp> class. These two
501 configurations are merged, and then configuration data whose hash key matches a
502 component name is merged with configuration for that component.
504 The configuration for a component is then passed to the C<new> method when a
505 component is constructed.
509 MyApp->config({ 'Model::Foo' => { bar => 'baz', overrides => 'me' } });
510 MyApp::Model::Foo->config({ quux => 'frob', 'overrides => 'this' });
512 will mean that C<MyApp::Model::Foo> receives the following data when
515 MyApp::Model::Foo->new({
523 around config => sub {
527 croak('Setting config after setup has been run is not allowed.')
528 if ( @_ and $c->setup_finished );
535 Returns the logging object instance. Unless it is already set, Catalyst
536 sets this up with a L<Catalyst::Log> object. To use your own log class,
537 set the logger with the C<< __PACKAGE__->log >> method prior to calling
538 C<< __PACKAGE__->setup >>.
540 __PACKAGE__->log( MyLogger->new );
545 $c->log->info( 'Now logging with my own logger!' );
547 Your log class should implement the methods described in
553 Returns 1 if debug mode is enabled, 0 otherwise.
555 You can enable debug mode in several ways:
559 =item By calling myapp_server.pl with the -d flag
561 =item With the environment variables MYAPP_DEBUG, or CATALYST_DEBUG
563 =item The -Debug option in your MyApp.pm
565 =item By declaring C<sub debug { 1 }> in your MyApp.pm.
569 Calling C<< $c->debug(1) >> has no effect.
575 =head2 $c->dispatcher
577 Returns the dispatcher instance. See L<Catalyst::Dispatcher>.
581 Returns the engine instance. See L<Catalyst::Engine>.
584 =head2 UTILITY METHODS
586 =head2 $c->path_to(@path)
588 Merges C<@path> with C<< $c->config->{home} >> and returns a
589 L<Path::Class::Dir> object. Note you can usually use this object as
590 a filename, but sometimes you will have to explicitly stringify it
591 yourself by calling the C<< ->stringify >> method.
595 $c->path_to( 'db', 'sqlite.db' );
600 my ( $c, @path ) = @_;
601 my $path = Path::Class::Dir->new( $c->config->{home}, @path );
602 if ( -d $path ) { return $path }
603 else { return Path::Class::File->new( $c->config->{home}, @path ) }
606 =head2 $c->plugin( $name, $class, @args )
608 Helper method for plugins. It creates a class data accessor/mutator and
609 loads and instantiates the given class.
611 MyApp->plugin( 'prototype', 'HTML::Prototype' );
613 $c->prototype->define_javascript_functions;
615 B<Note:> This method of adding plugins is deprecated. The ability
616 to add plugins like this B<will be removed> in a Catalyst 5.81.
617 Please do not use this functionality in new code.
622 my ( $class, $name, $plugin, @args ) = @_;
624 # See block comment in t/unit_core_plugin.t
625 $class->log->warn(qq/Adding plugin using the ->plugin method is deprecated, and will be removed in Catalyst 5.81/);
627 $class->_register_plugin( $plugin, 1 );
629 eval { $plugin->import };
630 $class->mk_classdata($name);
632 eval { $obj = $plugin->new(@args) };
635 Catalyst::Exception->throw( message =>
636 qq/Couldn't instantiate instant plugin "$plugin", "$@"/ );
640 $class->log->debug(qq/Initialized instant plugin "$plugin" as "$name"/)
646 Initializes the dispatcher and engine, loads any plugins, and loads the
647 model, view, and controller components. You may also specify an array
648 of plugins to load here, if you choose to not load them in the C<use
652 MyApp->setup( qw/-Debug/ );
657 my ( $class, @arguments ) = @_;
658 croak('Running setup more than once')
659 if ( $class->setup_finished );
661 unless ( $class->isa('Catalyst') ) {
663 Catalyst::Exception->throw(
664 message => qq/'$class' does not inherit from Catalyst/ );
667 if ( $class->arguments ) {
668 @arguments = ( @arguments, @{ $class->arguments } );
674 foreach (@arguments) {
678 ( $flags->{log} ) ? 'debug,' . $flags->{log} : 'debug';
680 elsif (/^-(\w+)=?(.*)$/) {
681 $flags->{ lc $1 } = $2;
684 push @{ $flags->{plugins} }, $_;
688 $class->setup_home( delete $flags->{home} );
690 $class->setup_log( delete $flags->{log} );
691 $class->setup_plugins( delete $flags->{plugins} );
692 $class->setup_dispatcher( delete $flags->{dispatcher} );
693 $class->setup_engine( delete $flags->{engine} );
694 $class->setup_stats( delete $flags->{stats} );
696 for my $flag ( sort keys %{$flags} ) {
698 if ( my $code = $class->can( 'setup_' . $flag ) ) {
699 &$code( $class, delete $flags->{$flag} );
702 $class->log->warn(qq/Unknown flag "$flag"/);
706 eval { require Catalyst::Devel; };
707 if( !$@ && $ENV{CATALYST_SCRIPT_GEN} && ( $ENV{CATALYST_SCRIPT_GEN} < $Catalyst::Devel::CATALYST_SCRIPT_GEN ) ) {
708 $class->log->warn(<<"EOF");
709 You are running an old script!
711 Please update by running (this will overwrite existing files):
712 catalyst.pl -force -scripts $class
714 or (this will not overwrite existing files):
715 catalyst.pl -scripts $class
720 if ( $class->debug ) {
721 my @plugins = map { "$_ " . ( $_->VERSION || '' ) } $class->registered_plugins;
724 my $column_width = Catalyst::Utils::term_width() - 6;
725 my $t = Text::SimpleTable->new($column_width);
726 $t->row($_) for @plugins;
727 $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" );
730 my $dispatcher = $class->dispatcher;
731 my $engine = $class->engine;
732 my $home = $class->config->{home};
734 $class->log->debug(sprintf(q/Loaded dispatcher "%s"/, blessed($dispatcher)));
735 $class->log->debug(sprintf(q/Loaded engine "%s"/, blessed($engine)));
739 ? $class->log->debug(qq/Found home "$home"/)
740 : $class->log->debug(qq/Home "$home" doesn't exist/)
741 : $class->log->debug(q/Couldn't find home/);
744 # Call plugins setup, this is stupid and evil.
745 # Also screws C3 badly on 5.10, hack to avoid.
747 no warnings qw/redefine/;
748 local *setup = sub { };
749 $class->setup unless $Catalyst::__AM_RESTARTING;
752 # Initialize our data structure
753 $class->components( {} );
755 $class->setup_components;
757 if ( $class->debug ) {
758 my $column_width = Catalyst::Utils::term_width() - 8 - 9;
759 my $t = Text::SimpleTable->new( [ $column_width, 'Class' ], [ 8, 'Type' ] );
760 for my $comp ( sort keys %{ $class->components } ) {
761 my $type = ref $class->components->{$comp} ? 'instance' : 'class';
762 $t->row( $comp, $type );
764 $class->log->debug( "Loaded components:\n" . $t->draw . "\n" )
765 if ( keys %{ $class->components } );
768 # Add our self to components, since we are also a component
769 if( $class->isa('Catalyst::Controller') ){
770 $class->components->{$class} = $class;
773 $class->setup_actions;
775 if ( $class->debug ) {
776 my $name = $class->config->{name} || 'Application';
777 $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
780 # Make sure that the application class becomes immutable at this point,
781 B::Hooks::EndOfScope::on_scope_end {
783 my $meta = Class::MOP::get_metaclass_by_name($class);
786 && ! { $meta->immutable_options }->{replace_constructor}
788 $class->isa('Class::Accessor::Fast')
789 || $class->isa('Class::Accessor')
792 warn "You made your application class ($class) immutable, "
793 . "but did not inline the\nconstructor. "
794 . "This will break catalyst, as your app \@ISA "
795 . "Class::Accessor(::Fast)?\nPlease pass "
796 . "(replace_constructor => 1)\nwhen making your class immutable.\n";
798 $meta->make_immutable(
799 replace_constructor => 1,
800 ) unless $meta->is_immutable;
803 $class->setup_finalize;
804 # Should be the last thing we do so that user things hooking
805 # setup_finalize can log..
806 $class->log->_flush() if $class->log->can('_flush');
807 return 1; # Explicit return true as people have __PACKAGE__->setup as the last thing in their class. HATE.
811 =head2 $app->setup_finalize
813 A hook to attach modifiers to.
814 Using C<< after setup => sub{}; >> doesn't work, because of quirky things done for plugin setup.
815 Also better than C< setup_finished(); >, as that is a getter method.
821 ## do stuff, i.e., determine a primary key column for sessions stored in a DB
823 $app->next::method(@_);
832 $class->setup_finished(1);
835 =head2 $c->welcome_message
837 Returns the Catalyst welcome HTML page.
841 sub welcome_message {
843 my $name = $c->config->{name};
844 my $logo = $c->uri_for('/static/images/catalyst_logo.png');
845 my $prefix = Catalyst::Utils::appprefix( ref $c );
846 $c->response->content_type('text/html; charset=utf-8');
848 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
849 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
850 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
852 <meta http-equiv="Content-Language" content="en" />
853 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
854 <title>$name on Catalyst $VERSION</title>
855 <style type="text/css">
858 background-color: #eee;
867 background-color: #ccc;
868 border: 1px solid #aaa;
873 font-family: verdana, tahoma, sans-serif;
876 font-family: verdana, tahoma, sans-serif;
879 text-decoration: none;
881 border-bottom: 1px dotted #bbb;
883 :link:hover, :visited:hover {
896 background-color: #fff;
897 border: 1px solid #aaa;
923 <h1><span id="appname">$name</span> on <a href="http://catalyst.perl.org">Catalyst</a>
928 <img src="$logo" alt="Catalyst Logo" />
930 <p>Welcome to the world of Catalyst.
931 This <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>
932 framework will make web development something you had
933 never expected it to be: Fun, rewarding, and quick.</p>
934 <h2>What to do now?</h2>
935 <p>That really depends on what <b>you</b> want to do.
936 We do, however, provide you with a few starting points.</p>
937 <p>If you want to jump right into web development with Catalyst
938 you might want to start with a tutorial.</p>
939 <pre>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial</a></code>
941 <p>Afterwards you can go on to check out a more complete look at our features.</p>
943 <code>perldoc <a href="http://cpansearch.perl.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod">Catalyst::Manual::Intro</a>
944 <!-- Something else should go here, but the Catalyst::Manual link seems unhelpful -->
946 <h2>What to do next?</h2>
947 <p>Next it's time to write an actual application. Use the
948 helper scripts to generate <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AController%3A%3A&mode=all">controllers</a>,
949 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&mode=all">models</a>, and
950 <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&mode=all">views</a>;
951 they can save you a lot of work.</p>
952 <pre><code>script/${prefix}_create.pl -help</code></pre>
953 <p>Also, be sure to check out the vast and growing
954 collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
955 you are likely to find what you need there.
959 <p>Catalyst has a very active community. Here are the main places to
960 get in touch with us.</p>
963 <a href="http://dev.catalyst.perl.org">Wiki</a>
966 <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst">Mailing-List</a>
969 <a href="irc://irc.perl.org/catalyst">IRC channel #catalyst on irc.perl.org</a>
972 <h2>In conclusion</h2>
973 <p>The Catalyst team hopes you will enjoy using Catalyst as much
974 as we enjoyed making it. Please contact us if you have ideas
975 for improvement or other feedback.</p>
983 =head1 INTERNAL METHODS
985 These methods are not meant to be used by end users.
987 =head2 $c->components
989 Returns a hash of components.
991 =head2 $c->context_class
993 Returns or sets the context class.
995 =head2 $c->dispatcher_class
997 Returns or sets the dispatcher class.
999 =head2 $c->engine_class
1001 Returns or sets the engine class.
1003 =head2 $c->handle_request( $class, @arguments )
1005 Called to handle each HTTP request.
1009 sub handle_request {
1010 my ( $class, @arguments ) = @_;
1012 # Always expect worst case!
1015 if ($class->debug) {
1016 my $secs = time - $START || 1;
1017 my $av = sprintf '%.3f', $COUNT / $secs;
1018 my $time = localtime time;
1019 $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***");
1022 my $c = $class->prepare(@arguments);
1024 $status = $c->finalize;
1027 if ( my $error = $@ ) {
1029 $class->log->error(qq/Caught exception in engine "$error"/);
1034 if(my $coderef = $class->log->can('_flush')){
1035 $class->log->$coderef();
1040 =head2 $c->prepare( @arguments )
1042 Creates a Catalyst context from an engine-specific request (Apache, CGI,
1048 my ( $class, @arguments ) = @_;
1051 # After the app/ctxt split, this should become an attribute based on something passed
1052 # into the application.
1053 $class->context_class( ref $class || $class ) unless $class->context_class;
1055 my $app = $class->new({});
1056 my $c = $class->context_class->new( application => $app );
1058 # For on-demand data
1059 $c->request->_context($c);
1060 $c->response->_context($c);
1062 #surely this is not the most efficient way to do things...
1063 $c->stats($class->stats_class->new)->enable($c->use_stats);
1065 $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
1068 #XXX reuse coderef from can
1069 # Allow engine to direct the prepare flow (for POE)
1070 if ( $c->engine->can('prepare') ) {
1071 $c->engine->prepare( $c, @arguments );
1074 $c->prepare_request(@arguments);
1075 $c->prepare_connection;
1076 $c->prepare_query_parameters;
1077 $c->prepare_headers;
1078 $c->prepare_cookies;
1081 # Prepare the body for reading, either by prepare_body
1082 # or the user, if they are using $c->read
1085 # Parse the body unless the user wants it on-demand
1086 unless ( $app->config->{parse_on_demand} ) {
1091 my $method = $c->req->method || '';
1092 my $path = $c->req->path;
1093 $path = '/' unless length $path;
1094 my $address = $c->req->address || '';
1096 $c->log->debug(qq/"$method" request for "$path" from "$address"/)
1104 =head2 $c->request_class
1106 Returns or sets the request class.
1108 =head2 $c->response_class
1110 Returns or sets the response class.
1118 sub run { my $c = shift; return $c->engine->run( $c, @_ ) }
1120 =head2 $c->set_action( $action, $code, $namespace, $attrs )
1122 Sets an action in a given namespace.
1126 sub set_action { my $c = shift; $c->dispatcher->set_action( $c, @_ ) }
1128 =head2 $c->setup_actions($component)
1130 Sets up actions for a component.
1134 sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
1136 =head2 $c->setup_components
1138 This method is called internally to set up the application's components.
1140 It finds modules by calling the L<locate_components> method, expands them to
1141 package names with the L<expand_component_module> method, and then installs
1142 each component into the application.
1144 The C<setup_components> config option is passed to both of the above methods.
1146 Installation of each component is performed by the L<setup_component> method,
1151 sub setup_components {
1154 my $config = $class->config->{ setup_components };
1156 my @comps = sort { length $a <=> length $b }
1157 $class->locate_components($config);
1158 my %comps = map { $_ => 1 } @comps;
1160 my $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @comps;
1161 $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
1162 qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
1163 ) if $deprecatedcatalyst_component_names;
1165 for my $component ( @comps ) {
1167 # We pass ignore_loaded here so that overlay files for (e.g.)
1168 # Model::DBI::Schema sub-classes are loaded - if it's in @comps
1169 # we know M::P::O found a file on disk so this is safe
1171 Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
1173 # Needs to be done as soon as the component is loaded, as loading a sub-component
1174 # (next time round the loop) can cause us to get the wrong metaclass..
1175 $class->_controller_init_base_classes($component);
1178 for my $component (@comps) {
1179 $class->components->{ $component } = $class->setup_component($component);
1180 for my $component ($class->expand_component_module( $component, $config )) {
1181 next if $comps{$component};
1182 $class->_controller_init_base_classes($component); # Also cover inner packages
1183 $class->components->{ $component } = $class->setup_component($component);
1188 =head2 $c->locate_components( $setup_component_config )
1190 This method is meant to provide a list of component modules that should be
1191 setup for the application. By default, it will use L<Module::Pluggable>.
1193 Specify a C<setup_components> config option to pass additional options directly
1194 to L<Module::Pluggable>. To add additional search paths, specify a key named
1195 C<search_extra> as an array reference. Items in the array beginning with C<::>
1196 will have the application class name prepended to them.
1200 sub locate_components {
1204 my @paths = qw( ::Controller ::C ::Model ::M ::View ::V );
1205 my $extra = delete $config->{ search_extra } || [];
1207 push @paths, @$extra;
1209 my $locator = Module::Pluggable::Object->new(
1210 search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
1214 my @comps = $locator->plugins;
1219 =head2 $c->expand_component_module( $component, $setup_component_config )
1221 Components found by C<locate_components> will be passed to this method, which
1222 is expected to return a list of component (package) names to be set up.
1226 sub expand_component_module {
1227 my ($class, $module) = @_;
1228 return Devel::InnerPackage::list_packages( $module );
1231 =head2 $c->setup_component
1235 # FIXME - Ugly, ugly hack to ensure the we force initialize non-moose base classes
1236 # nearest to Catalyst::Controller first, no matter what order stuff happens
1237 # to be loaded. There are TODO tests in Moose for this, see
1238 # f2391d17574eff81d911b97be15ea51080500003
1239 sub _controller_init_base_classes {
1240 my ($app_class, $component) = @_;
1241 return unless $component->isa('Catalyst::Controller');
1242 foreach my $class ( reverse @{ mro::get_linear_isa($component) } ) {
1243 Moose::Meta::Class->initialize( $class )
1244 unless find_meta($class);
1248 sub setup_component {
1249 my( $class, $component ) = @_;
1251 unless ( $component->can( 'COMPONENT' ) ) {
1255 my $suffix = Catalyst::Utils::class2classsuffix( $component );
1256 my $config = $class->config->{ $suffix } || {};
1257 # Stash catalyst_component_name in the config here, so that custom COMPONENT
1258 # methods also pass it. local to avoid pointlessly shitting in config
1259 # for the debug screen, as $component is already the key name.
1260 local $config->{catalyst_component_name} = $component;
1262 my $instance = eval { $component->COMPONENT( $class, $config ); };
1264 if ( my $error = $@ ) {
1266 Catalyst::Exception->throw(
1267 message => qq/Couldn't instantiate component "$component", "$error"/
1271 unless (blessed $instance) {
1272 my $metaclass = Moose::Util::find_meta($component);
1273 my $method_meta = $metaclass->find_method_by_name('COMPONENT');
1274 my $component_method_from = $method_meta->associated_metaclass->name;
1275 my $value = defined($instance) ? $instance : 'undef';
1276 Catalyst::Exception->throw(
1278 qq/Couldn't instantiate component "$component", COMPONENT() method (from $component_method_from) didn't return an object-like value (value was $value)./
1284 =head2 $c->setup_dispatcher
1290 sub setup_dispatcher {
1291 my ( $class, $dispatcher ) = @_;
1294 $dispatcher = 'Catalyst::Dispatcher::' . $dispatcher;
1297 if ( my $env = Catalyst::Utils::env_value( $class, 'DISPATCHER' ) ) {
1298 $dispatcher = 'Catalyst::Dispatcher::' . $env;
1301 unless ($dispatcher) {
1302 $dispatcher = $class->dispatcher_class;
1305 Class::MOP::load_class($dispatcher);
1307 # dispatcher instance
1308 $class->dispatcher( $dispatcher->new );
1311 =head2 $c->setup_engine
1318 my ( $class, $engine ) = @_;
1321 $engine = 'Catalyst::Engine::' . $engine;
1324 if ( my $env = Catalyst::Utils::env_value( $class, 'ENGINE' ) ) {
1325 $engine = 'Catalyst::Engine::' . $env;
1328 if ( $ENV{MOD_PERL} ) {
1329 my $meta = Class::MOP::get_metaclass_by_name($class);
1331 # create the apache method
1332 $meta->add_method('apache' => sub { shift->engine->apache });
1334 my ( $software, $version ) =
1335 $ENV{MOD_PERL} =~ /^(\S+)\/(\d+(?:[\.\_]\d+)+)/;
1338 $version =~ s/(\.[^.]+)\./$1/g;
1340 if ( $software eq 'mod_perl' ) {
1344 if ( $version >= 1.99922 ) {
1345 $engine = 'Catalyst::Engine::Apache2::MP20';
1348 elsif ( $version >= 1.9901 ) {
1349 $engine = 'Catalyst::Engine::Apache2::MP19';
1352 elsif ( $version >= 1.24 ) {
1353 $engine = 'Catalyst::Engine::Apache::MP13';
1357 Catalyst::Exception->throw( message =>
1358 qq/Unsupported mod_perl version: $ENV{MOD_PERL}/ );
1363 # install the correct mod_perl handler
1364 if ( $version >= 1.9901 ) {
1365 *handler = sub : method {
1366 shift->handle_request(@_);
1370 *handler = sub ($$) { shift->handle_request(@_) };
1375 elsif ( $software eq 'Zeus-Perl' ) {
1376 $engine = 'Catalyst::Engine::Zeus';
1380 Catalyst::Exception->throw(
1381 message => qq/Unsupported mod_perl: $ENV{MOD_PERL}/ );
1386 $engine = $class->engine_class;
1389 Class::MOP::load_class($engine);
1391 # check for old engines that are no longer compatible
1393 if ( $engine->isa('Catalyst::Engine::Apache')
1394 && !Catalyst::Engine::Apache->VERSION )
1399 elsif ( $engine->isa('Catalyst::Engine::Server::Base')
1400 && Catalyst::Engine::Server->VERSION le '0.02' )
1405 elsif ($engine->isa('Catalyst::Engine::HTTP::POE')
1406 && $engine->VERSION eq '0.01' )
1411 elsif ($engine->isa('Catalyst::Engine::Zeus')
1412 && $engine->VERSION eq '0.01' )
1418 Catalyst::Exception->throw( message =>
1419 qq/Engine "$engine" is not supported by this version of Catalyst/
1424 $class->engine( $engine->new );
1427 =head2 $c->setup_home
1429 Sets up the home directory.
1434 my ( $class, $home ) = @_;
1436 if ( my $env = Catalyst::Utils::env_value( $class, 'HOME' ) ) {
1440 $home ||= Catalyst::Utils::home($class);
1443 #I remember recently being scolded for assigning config values like this
1444 $class->config->{home} ||= $home;
1445 $class->config->{root} ||= Path::Class::Dir->new($home)->subdir('root');
1449 =head2 $c->setup_log
1451 Sets up log by instantiating a L<Catalyst::Log|Catalyst::Log> object and
1452 passing it to C<log()>. Pass in a comma-delimited list of levels to set the
1455 This method also installs a C<debug> method that returns a true value into the
1456 catalyst subclass if the "debug" level is passed in the comma-delimited list,
1457 or if the C<$CATALYST_DEBUG> environment variable is set to a true value.
1459 Note that if the log has already been setup, by either a previous call to
1460 C<setup_log> or by a call such as C<< __PACKAGE__->log( MyLogger->new ) >>,
1461 that this method won't actually set up the log object.
1466 my ( $class, $levels ) = @_;
1469 $levels =~ s/^\s+//;
1470 $levels =~ s/\s+$//;
1471 my %levels = map { $_ => 1 } split /\s*,\s*/, $levels;
1473 my $env_debug = Catalyst::Utils::env_value( $class, 'DEBUG' );
1474 if ( defined $env_debug ) {
1475 $levels{debug} = 1 if $env_debug; # Ugly!
1476 delete($levels{debug}) unless $env_debug;
1479 unless ( $class->log ) {
1480 $class->log( Catalyst::Log->new(keys %levels) );
1483 if ( $levels{debug} ) {
1484 Class::MOP::get_metaclass_by_name($class)->add_method('debug' => sub { 1 });
1485 $class->log->debug('Debug messages enabled');
1489 =head2 $c->setup_plugins
1495 =head2 $c->setup_stats
1497 Sets up timing statistics class.
1502 my ( $class, $stats ) = @_;
1504 Catalyst::Utils::ensure_class_loaded($class->stats_class);
1506 my $env = Catalyst::Utils::env_value( $class, 'STATS' );
1507 if ( defined($env) ? $env : ($stats || $class->debug ) ) {
1508 Class::MOP::get_metaclass_by_name($class)->add_method('use_stats' => sub { 1 });
1509 $class->log->debug('Statistics enabled');
1514 =head2 $c->registered_plugins
1516 Returns a sorted list of the plugins which have either been stated in the
1517 import list or which have been added via C<< MyApp->plugin(@args); >>.
1519 If passed a given plugin name, it will report a boolean value indicating
1520 whether or not that plugin is loaded. A fully qualified name is required if
1521 the plugin name does not begin with C<Catalyst::Plugin::>.
1523 if ($c->registered_plugins('Some::Plugin')) {
1531 sub registered_plugins {
1533 return sort keys %{ $proto->_plugins } unless @_;
1535 return 1 if exists $proto->_plugins->{$plugin};
1536 return exists $proto->_plugins->{"Catalyst::Plugin::$plugin"};
1539 sub _register_plugin {
1540 my ( $proto, $plugin, $instant ) = @_;
1541 my $class = ref $proto || $proto;
1543 Class::MOP::load_class( $plugin );
1545 $proto->_plugins->{$plugin} = 1;
1548 if ( my $meta = Class::MOP::get_metaclass_by_name($class) ) {
1549 my @superclasses = ($plugin, $meta->superclasses );
1550 $meta->superclasses(@superclasses);
1552 unshift @{"$class\::ISA"}, $plugin;
1559 my ( $class, $plugins ) = @_;
1561 $class->_plugins( {} ) unless $class->_plugins;
1564 my @plugins = Catalyst::Utils::resolve_namespace($class . '::Plugin', 'Catalyst::Plugin', @$plugins);
1566 for my $plugin ( reverse @plugins ) {
1567 Class::MOP::load_class($plugin);
1568 my $meta = find_meta($plugin);
1569 next if $meta && $meta->isa('Moose::Meta::Role');
1571 $class->_register_plugin($plugin);
1576 grep { $_ && blessed($_) && $_->isa('Moose::Meta::Role') }
1577 map { find_meta($_) }
1580 Moose::Util::apply_all_roles(
1586 =head2 $c->stats_class
1588 Returns or sets the stats (timing statistics) class.
1590 =head2 $c->use_stats
1592 Returns 1 when stats collection is enabled. Stats collection is enabled
1593 when the -Stats options is set, debug is on or when the <MYAPP>_STATS
1594 environment variable is set.
1596 Note that this is a static method, not an accessor and should be overridden
1597 by declaring C<sub use_stats { 1 }> in your MyApp.pm, not by calling C<< $c->use_stats(1) >>.
1605 Returns the Catalyst version number. Mostly useful for "powered by"
1606 messages in template systems.
1610 sub version { return $Catalyst::VERSION }
1612 =head1 CONFIGURATION
1614 There are a number of 'base' config variables which can be set:
1620 C<default_model> - The default model picked if you say C<< $c->model >>. See L</$c->model($name)>.
1624 C<default_view> - The default view to be rendered or returned when C<< $c->view >>. See L</$c->view($name)>.
1629 C<disable_component_resolution_regex_fallback> - Turns
1630 off the deprecated component resolution functionality so
1631 that if any of the component methods (e.g. C<< $c->controller('Foo') >>)
1632 are called then regex search will not be attempted on string values and
1633 instead C<undef> will be returned.
1637 C<home> - The application home directory. In an uninstalled application,
1638 this is the top level application directory. In an installed application,
1639 this will be the directory containing C<< MyApp.pm >>.
1643 C<ignore_frontend_proxy> - See L</PROXY SUPPORT>
1647 C<name> - The name of the application in debug messages and the debug and
1652 C<parse_on_demand> - The request body (for example file uploads) will not be parsed
1653 until it is accessed. This allows you to (for example) check authentication (and reject
1654 the upload) before actually recieving all the data. See L</ON-DEMAND PARSER>
1658 C<root> - The root directory for templates. Usually this is just a
1659 subdirectory of the home directory, but you can set it to change the
1660 templates to a different directory.
1664 C<search_extra> - Array reference passed to Module::Pluggable to for additional
1665 namespaces from which components will be loaded (and constructed and stored in
1666 C<< $c->components >>).
1670 C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >>
1671 to be shown in hit debug tables in the test server.
1675 C<using_frontend_proxy> - See L</PROXY SUPPORT>.
1679 =head1 INTERNAL ACTIONS
1681 Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
1682 C<_ACTION>, and C<_END>. These are by default not shown in the private
1683 action table, but you can make them visible with a config parameter.
1685 MyApp->config(show_internal_actions => 1);
1687 =head1 ON-DEMAND PARSER
1689 The request body is usually parsed at the beginning of a request,
1690 but if you want to handle input yourself, you can enable on-demand
1691 parsing with a config parameter.
1693 MyApp->config(parse_on_demand => 1);
1695 =head1 PROXY SUPPORT
1697 Many production servers operate using the common double-server approach,
1698 with a lightweight frontend web server passing requests to a larger
1699 backend server. An application running on the backend server must deal
1700 with two problems: the remote user always appears to be C<127.0.0.1> and
1701 the server's hostname will appear to be C<localhost> regardless of the
1702 virtual host that the user connected through.
1704 Catalyst will automatically detect this situation when you are running
1705 the frontend and backend servers on the same machine. The following
1706 changes are made to the request.
1708 $c->req->address is set to the user's real IP address, as read from
1709 the HTTP X-Forwarded-For header.
1711 The host value for $c->req->base and $c->req->uri is set to the real
1712 host, as read from the HTTP X-Forwarded-Host header.
1714 Additionally, you may be running your backend application on an insecure
1715 connection (port 80) while your frontend proxy is running under SSL. If there
1716 is a discrepancy in the ports, use the HTTP header C<X-Forwarded-Port> to
1717 tell Catalyst what port the frontend listens on. This will allow all URIs to
1718 be created properly.
1720 In the case of passing in:
1722 X-Forwarded-Port: 443
1724 All calls to C<uri_for> will result in an https link, as is expected.
1726 Obviously, your web server must support these headers for this to work.
1728 In a more complex server farm environment where you may have your
1729 frontend proxy server(s) on different machines, you will need to set a
1730 configuration option to tell Catalyst to read the proxied data from the
1733 MyApp->config(using_frontend_proxy => 1);
1735 If you do not wish to use the proxy support at all, you may set:
1737 MyApp->config(ignore_frontend_proxy => 1);
1739 =head1 THREAD SAFETY
1741 Catalyst has been tested under Apache 2's threading C<mpm_worker>,
1742 C<mpm_winnt>, and the standalone forking HTTP server on Windows. We
1743 believe the Catalyst core to be thread-safe.
1745 If you plan to operate in a threaded environment, remember that all other
1746 modules you are using must also be thread-safe. Some modules, most notably
1747 L<DBD::SQLite>, are not thread-safe.
1753 Join #catalyst on irc.perl.org.
1757 http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
1758 http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst-dev
1762 http://catalyst.perl.org
1766 http://dev.catalyst.perl.org
1770 =head2 L<Task::Catalyst> - All you need to start with Catalyst
1772 =head2 L<Catalyst::Manual> - The Catalyst Manual
1774 =head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components
1776 =head2 L<Catalyst::Engine> - Core engine
1778 =head2 L<Catalyst::Log> - Log class.
1780 =head2 L<Catalyst::Request> - Request object
1782 =head2 L<Catalyst::Response> - Response object
1784 =head2 L<Catalyst::Test> - The test suite.
1786 =head1 PROJECT FOUNDER
1788 sri: Sebastian Riedel <sri@cpan.org>
1794 acme: Leon Brocard <leon@astray.com>
1796 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
1800 Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
1804 andyg: Andy Grundman <andy@hybridized.org>
1806 audreyt: Audrey Tang
1808 bricas: Brian Cassidy <bricas@cpan.org>
1810 Caelum: Rafael Kitover <rkitover@io.com>
1812 chansen: Christian Hansen
1814 chicks: Christopher Hicks
1816 Chisel Wright C<pause@herlpacker.co.uk>
1818 Danijel Milicevic C<me@danijel.de>
1820 David Kamholz E<lt>dkamholz@cpan.orgE<gt>
1822 David Naughton, C<naughton@umn.edu>
1826 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
1830 dwc: Daniel Westermann-Clark <danieltwc@cpan.org>
1832 esskar: Sascha Kiefer
1834 fireartist: Carl Franks <cfranks@cpan.org>
1836 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
1838 gabb: Danijel Milicevic
1842 Gavin Henry C<ghenry@perl.me.uk>
1846 groditi: Guillermo Roditi <groditi@gmail.com>
1848 hobbs: Andrew Rodland <andrew@cleverdomain.org>
1850 ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
1852 jcamacho: Juan Camacho
1854 jester: Jesse Sheidlower C<jester@panix.com>
1856 jhannah: Jay Hannah <jay@jays.net>
1862 jon: Jon Schutz <jjschutz@cpan.org>
1864 Jonathan Rockway C<< <jrockway@cpan.org> >>
1866 Kieren Diment C<kd@totaldatasolution.com>
1868 konobi: Scott McWhirter <konobi@cpan.org>
1870 marcus: Marcus Ramberg <mramberg@cpan.org>
1872 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
1874 mst: Matt S. Trout <mst@shadowcatsystems.co.uk>
1878 naughton: David Naughton
1880 ningu: David Kamholz <dkamholz@cpan.org>
1882 nothingmuch: Yuval Kogman <nothingmuch@woobling.org>
1884 numa: Dan Sully <daniel@cpan.org>
1888 omega: Andreas Marienborg
1890 Oleg Kostyuk <cub.uanic@gmail.com>
1892 phaylon: Robert Sedlacek <phaylon@dunkelheit.at>
1894 rafl: Florian Ragwitz <rafl@debian.org>
1896 random: Roland Lammel <lammel@cpan.org>
1898 Robert Sedlacek C<< <rs@474.at> >>
1902 t0m: Tomas Doran <bobtfish@bobtfish.net>
1906 Viljo Marrandi C<vilts@yahoo.com>
1908 Will Hawes C<info@whawes.co.uk>
1910 willert: Sebastian Willert <willert@cpan.org>
1912 Yuval Kogman, C<nothingmuch@woobling.org>
1916 This library is free software. You can redistribute it and/or modify it under
1917 the same terms as Perl itself.
1923 __PACKAGE__->meta->make_immutable;