Merge branch pass_component_names:
Tomas Doran [Sat, 1 Aug 2009 00:39:39 +0000 (00:39 +0000)]
svn merge -r  10899:10927  http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/branches/pass_component_names

1  2 
Makefile.PL
lib/Catalyst.pm
lib/Catalyst/Action.pm
lib/Catalyst/Component.pm
lib/Catalyst/Controller.pm

diff --combined Makefile.PL
@@@ -11,7 -11,7 +11,7 @@@ requires 'B::Hooks::EndOfScope' => '0.0
  requires 'MooseX::Emulate::Class::Accessor::Fast' => '0.00801';
  requires 'Class::MOP' => '0.83';
  requires 'Moose' => '0.78';
- requires 'MooseX::MethodAttributes::Inheritable' => '0.12';
+ requires 'MooseX::MethodAttributes::Inheritable' => '0.14';
  requires 'Carp';
  requires 'Class::C3::Adopt::NEXT' => '0.07';
  requires 'CGI::Simple::Cookie';
@@@ -23,7 -23,7 +23,7 @@@ requires 'HTTP::Request'
  requires 'HTTP::Response';
  requires 'HTTP::Request::AsCGI' => '0.8';
  requires 'LWP::UserAgent';
 -requires 'Module::Pluggable' => '3.01';
 +requires 'Module::Pluggable' => '3.9';
  requires 'Path::Class' => '0.09';
  requires 'Scalar::Util';
  requires 'Sub::Exporter';
diff --combined lib/Catalyst.pm
@@@ -335,11 -335,9 +335,11 @@@ call to forward
      $c->forward(qw/MyApp::Model::DBIC::Foo do_stuff/);
      $c->forward('MyApp::View::TT');
  
 -Note that forward implies an C<<eval { }>> around the call (actually
 -C<execute> does), thus de-fatalizing all 'dies' within the called
 -action. If you want C<die> to propagate you need to do something like:
 +Note that L<< forward|/"$c->forward( $action [, \@arguments ] )" >> implies
 +an C<< eval { } >> around the call (actually
 +L<< execute|/"$c->execute( $class, $coderef )" >> does), thus de-fatalizing
 +all 'dies' within the called action. If you want C<die> to propagate you
 +need to do something like:
  
      $c->forward('foo');
      die $c->error if $c->error;
@@@ -359,8 -357,8 +359,8 @@@ sub forward { my $c = shift; no warning
  
  =head2 $c->detach()
  
 -The same as C<forward>, but doesn't return to the previous action when
 -processing is finished.
 +The same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, but
 +doesn't return to the previous action when processing is finished.
  
  When called with no arguments it escapes the processing chain entirely.
  
@@@ -372,27 -370,23 +372,27 @@@ sub detach { my $c = shift; $c->dispatc
  
  =head2 $c->visit( $class, $method, [, \@captures, \@arguments ] )
  
 -Almost the same as C<forward>, but does a full dispatch, instead of just
 -calling the new C<$action> / C<$class-E<gt>$method>. This means that C<begin>,
 -C<auto> and the method you go to are called, just like a new request.
 +Almost the same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>,
 +but does a full dispatch, instead of just calling the new C<$action> /
 +C<< $class->$method >>. This means that C<begin>, C<auto> and the method
 +you go to are called, just like a new request.
  
  In addition both C<< $c->action >> and C<< $c->namespace >> are localized.
 -This means, for example, that $c->action methods such as C<name>, C<class> and
 -C<reverse> return information for the visited action when they are invoked
 -within the visited action.  This is different from the behavior of C<forward>
 -which continues to use the $c->action object from the caller action even when
 +This means, for example, that C<< $c->action >> methods such as
 +L<name|Catalyst::Action/name>, L<class|Catalyst::Action/class> and
 +L<reverse|Catalyst::Action/reverse> return information for the visited action
 +when they are invoked within the visited action.  This is different from the
 +behavior of L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, which
 +continues to use the $c->action object from the caller action even when
  invoked from the callee.
  
 -C<$c-E<gt>stash> is kept unchanged.
 +C<< $c->stash >> is kept unchanged.
  
 -In effect, C<visit> allows you to "wrap" another action, just as it
 -would have been called by dispatching from a URL, while the analogous
 -C<go> allows you to transfer control to another action as if it had
 -been reached directly from a URL.
 +In effect, L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >>
 +allows you to "wrap" another action, just as it would have been called by
 +dispatching from a URL, while the analogous
 +L<< go|/"$c->go( $action [, \@captures, \@arguments ] )" >> allows you to
 +transfer control to another action as if it had been reached directly from a URL.
  
  =cut
  
@@@ -402,12 -396,12 +402,12 @@@ sub visit { my $c = shift; $c->dispatch
  
  =head2 $c->go( $class, $method, [, \@captures, \@arguments ] )
  
 -Almost the same as C<detach>, but does a full dispatch like C<visit>,
 +Almost the same as L<< detach|/"$c->detach( $action [, \@arguments ] )" >>, but does a full dispatch like L</visit>,
  instead of just calling the new C<$action> /
 -C<$class-E<gt>$method>. This means that C<begin>, C<auto> and the
 +C<< $class->$method >>. This means that C<begin>, C<auto> and the
  method you visit are called, just like a new request.
  
 -C<$c-E<gt>stash> is kept unchanged.
 +C<< $c->stash >> is kept unchanged.
  
  =cut
  
@@@ -824,8 -818,8 +824,8 @@@ Returns or takes a hashref containing t
  
      __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
  
 -You can also use a C<YAML>, C<XML> or C<Config::General> config file
 -like myapp.conf in your applications home directory. See
 +You can also use a C<YAML>, C<XML> or L<Config::General> config file
 +like C<myapp.conf> in your applications home directory. See
  L<Catalyst::Plugin::ConfigLoader>.
  
  =head3 Cascading configuration
@@@ -924,7 -918,7 +924,7 @@@ Returns the engine instance. See L<Cata
  Merges C<@path> with C<< $c->config->{home} >> and returns a
  L<Path::Class::Dir> object. Note you can usually use this object as
  a filename, but sometimes you will have to explicitly stringify it
 -yourself by calling the C<<->stringify>> method.
 +yourself by calling the C<< ->stringify >> method.
  
  For example:
  
@@@ -1164,42 -1158,30 +1164,42 @@@ sub setup_finalize 
      $class->setup_finished(1);
  }
  
 -=head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
 -
  =head2 $c->uri_for( $path, @args?, \%query_values? )
  
 -=over
 -
 -=item $action
 -
 -A Catalyst::Action object representing the Catalyst action you want to
 -create a URI for. To get one for an action in the current controller,
 -use C<< $c->action('someactionname') >>. To get one from different
 -controller, fetch the controller using C<< $c->controller() >>, then
 -call C<action_for> on it.
 -
 -You can maintain the arguments captured by an action (e.g.: Regex, Chained)
 -using C<< $c->req->captures >>.
 +=head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
  
 -  # For the current action
 -  $c->uri_for($c->action, $c->req->captures);
 +Constructs an absolute L<URI> object based on the application root, the
 +provided path, and the additional arguments and query parameters provided.
 +When used as a string, provides a textual URI.
 +
 +If the first argument is a string, it is taken as a public URI path relative
 +to C<< $c->namespace >> (if it doesn't begin with a forward slash) or
 +relative to the application root (if it does). It is then merged with 
 +C<< $c->request->base >>; any C<@args> are appended as additional path
 +components; and any C<%query_values> are appended as C<?foo=bar> parameters.
 +
 +If the first argument is a L<Catalyst::Action> it represents an action which
 +will have its path resolved using C<< $c->dispatcher->uri_for_action >>. The
 +optional C<\@captures> argument (an arrayref) allows passing the captured
 +variables that are needed to fill in the paths of Chained and Regex actions;
 +once the path is resolved, C<uri_for> continues as though a path was
 +provided, appending any arguments or parameters and creating an absolute
 +URI.
 +
 +The captures for the current request can be found in 
 +C<< $c->request->captures >>, and actions can be resolved using
 +C<< Catalyst::Controller->action_for($name) >>. If you have a private action
 +path, use C<< $c->uri_for_action >> instead.
 +
 +  # Equivalent to $c->req->uri
 +  $c->uri_for($c->action, $c->req->captures, 
 +      @{ $c->req->args }, $c->req->params);
  
    # For the Foo action in the Bar controller
 -  $c->uri_for($c->controller('Bar')->action_for('Foo'), $c->req->captures);
 +  $c->uri_for($c->controller('Bar')->action_for('Foo'));
  
 -=back
 +  # Path to a static resource
 +  $c->uri_for('/static/images/logo.png');
  
  =cut
  
@@@ -1624,6 -1606,25 +1624,6 @@@ sub _stats_finish_execute 
      $c->stats->profile( end => $info );
  }
  
 -=head2 $c->_localize_fields( sub { }, \%keys );
 -
 -=cut
 -
 -#Why does this exist? This is no longer safe and WILL NOT WORK.
 -# it doesnt seem to be used anywhere. can we remove it?
 -sub _localize_fields {
 -    my ( $c, $localized, $code ) = ( @_ );
 -
 -    my $request = delete $localized->{request} || {};
 -    my $response = delete $localized->{response} || {};
 -
 -    local @{ $c }{ keys %$localized } = values %$localized;
 -    local @{ $c->request }{ keys %$request } = values %$request;
 -    local @{ $c->response }{ keys %$response } = values %$response;
 -
 -    $code->();
 -}
 -
  =head2 $c->finalize
  
  Finalizes the request.
@@@ -2133,7 -2134,7 +2133,7 @@@ reference. Items in the array beginnin
  application class name prepended to them.
  
  All components found will also have any
 -L<Devel::InnerPackage|inner packages> loaded and set up as components.
 +L<inner packages|Devel::InnerPackage> loaded and set up as components.
  Note, that modules which are B<not> an I<inner package> of the main
  file namespace loaded will not be instantiated as components.
  
@@@ -2215,7 -2216,11 +2215,10 @@@ sub setup_component 
  
      my $suffix = Catalyst::Utils::class2classsuffix( $component );
      my $config = $class->config->{ $suffix } || {};
 -    # Stash _component_name in the config here, so that custom COMPONENT
 -    # methods also pass it. local to avoid pointlessly shitting in config
 -    # for the debug screen, as $component is already the key name.
 -    local $config->{_component_name} = $component;
 -
++    $config->{_component_name} = $component; # Put this in args here, rather
++                                             # than in COMPONENT as there
++                                             # are lots of custom COMPONENT
++                                             # methods..
      my $instance = eval { $component->COMPONENT( $class, $config ); };
  
      if ( my $error = $@ ) {
@@@ -2682,7 -2687,7 +2685,7 @@@ Wiki
  
  =head2 L<Catalyst::Manual> - The Catalyst Manual
  
 -=head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
 +=head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components
  
  =head2 L<Catalyst::Engine> - Core engine
  
@@@ -2740,14 -2745,10 +2743,14 @@@ Gary Ashton Jone
  
  Geoff Richards
  
 +hobbs: Andrew Rodland <andrew@cleverdomain.org>
 +
  ilmari: Dagfinn Ilmari MannsÃ¥ker <ilmari@ilmari.org>
  
  jcamacho: Juan Camacho
  
 +jester: Jesse Sheidlower
 +
  jhannah: Jay Hannah <jay@jays.net>
  
  Jody Belka
@@@ -2756,8 -2757,6 +2759,8 @@@ Johan Lindstro
  
  jon: Jon Schutz <jjschutz@cpan.org>
  
 +konobi: Scott McWhirter <konobi@cpan.org>
 +
  marcus: Marcus Ramberg <mramberg@cpan.org>
  
  miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
@@@ -2788,6 -2787,8 +2791,6 @@@ random: Roland Lammel <lammel@cpan.org
  
  sky: Arthur Bergman
  
 -the_jester: Jesse Sheidlower
 -
  t0m: Tomas Doran <bobtfish@bobtfish.net>
  
  Ulf Edvinsson
diff --combined lib/Catalyst/Action.pm
@@@ -55,8 -55,6 +55,6 @@@ use overload 
  
  no warnings 'recursion';
  
- #__PACKAGE__->mk_accessors(qw/class namespace reverse attributes name code/);
  sub dispatch {    # Execute ourselves against a context
      my ( $self, $c ) = @_;
      return $c->execute( $self->class, $self );
@@@ -105,7 -103,9 +103,9 @@@ and so on. This determines how the acti
  
  =head2 class
  
- Returns the class name where this action is defined.
+ Returns the name of the component where this action is defined.
+ Derived by calling the L<Catalyst::Component/_component_name|_component_name>
+ method on each component.
  
  =head2 code
  
@@@ -113,7 -113,7 +113,7 @@@ Returns a code reference to this action
  
  =head2 dispatch( $c )
  
 -Dispatch this action against a context
 +Dispatch this action against a context.
  
  =head2 execute( $controller, $c, @args )
  
@@@ -145,11 -145,11 +145,11 @@@ C<private_path> of an action is always 
  
  =head2 name
  
 -returns the sub name of this action.
 +Returns the sub name of this action.
  
  =head2 meta
  
 -Provided by Moose
 +Provided by Moose.
  
  =head1 AUTHORS
  
@@@ -60,6 -60,15 +60,8 @@@ component loader with config() support 
  __PACKAGE__->mk_classdata('_plugins');
  __PACKAGE__->mk_classdata('_config');
  
 -has _component_name => ( is => 'ro' ); # Cannot be required => 1 as context
 -                                       # class @ISA component - HATE
 -# Make accessor callable as a class method, as we need to call setup_actions
 -# on the application class, which we don't have an instance of, ewwwww
 -around _component_name => sub {
 -    my ($orig, $self) = (shift, shift);
 -    blessed($self) ? $self->$orig(@_) : $self;
 -};
++has _component_name => ( is => 'ro' );
  sub BUILDARGS {
      my $class = shift;
      my $args = {};
  }
  
  sub COMPONENT {
-     my ( $self, $c ) = @_;
+     my ( $class, $c ) = @_;
  
      # Temporary fix, some components does not pass context to constructor
      my $arguments = ( ref( $_[-1] ) eq 'HASH' ) ? $_[-1] : {};
-     if( my $next = $self->next::can ){
-       my $class = blessed $self || $self;
+     if ( my $next = $class->next::can ) {
        my ($next_package) = Class::MOP::get_code_info($next);
        warn "There is a COMPONENT method resolving after Catalyst::Component in ${next_package}.\n";
        warn "This behavior can no longer be supported, and so your application is probably broken.\n";
        warn "Your linearized isa hierarchy is: " . join(', ', @{ mro::get_linear_isa($class) }) . "\n";
        warn "Please see perldoc Catalyst::Upgrading for more information about this issue.\n";
      }
-     return $self->new($c, $arguments);
+     return $class->new($c, $arguments);
  }
  
  sub config {
@@@ -171,6 -179,6 +172,15 @@@ something like this
        return $class->new($app, $args);
    }
  
++=head2 _component_name
++
++The name of the component within an application. This is used to
++pass the component's name to actions generated (becoming
++C<< $action->class >>). This is needed so that the L</COMPONENT> method can
++return an instance of a different class (e.g. a L<Class::MOP> anonymous class),
++(as finding the component name by C<< ref($self) >> will not work correctly in
++such cases).
++
  =head2 $c->config
  
  =head2 $c->config($hashref)
@@@ -156,7 -156,7 +156,7 @@@ around action_namespace => sub 
          }
      }
  
-     my $namespace = Catalyst::Utils::class2prefix(ref($self) || $self, $case_s) || '';
 -    my $namespace = Catalyst::Utils::class2prefix($self->_component_name, $case_s) || '';
++    my $namespace = Catalyst::Utils::class2prefix(ref($self) ? $self->_component_name : $self, $case_s) || '';
      $self->$orig($namespace) if ref($self);
      return $namespace;
  };
@@@ -190,7 -190,7 +190,7 @@@ sub get_action_methods 
          @methods,
          map {
              $meta->find_method_by_name($_)
-               || confess( 'Action "' 
+               || confess( 'Action "'
                    . $_
                    . '" is not available from controller '
                    . ( ref $self ) )
@@@ -207,10 -207,15 +207,10 @@@ sub register_actions 
  
  sub register_action_methods {
      my ( $self, $c, @methods ) = @_;
-     my $class = ref $self || $self;
 -    my $class = $self->_component_name;
++    my $class = blessed($self) ? $self->_component_name : $self;
      #this is still not correct for some reason.
      my $namespace = $self->action_namespace($c);
  
 -    # Uncomment as soon as you fix the tests :)
 -    #if (!blessed($self) && $self eq $c && scalar(@methods)) {
 -    #    $c->log->warn("Action methods found defined in your application class, $self. This is deprecated, please move them into a Root controller.");
 -    #}
 -
      foreach my $method (@methods) {
          my $name = $method->name;
          my $attributes = $method->attributes;