added support for non Catalyst::Base components
Christian Hansen [Fri, 27 May 2005 22:31:17 +0000 (22:31 +0000)]
Build.PL
Changes
lib/Catalyst.pm
lib/Catalyst/Base.pm
lib/Catalyst/Dispatcher.pm
lib/Catalyst/Engine.pm
lib/Catalyst/Request.pm

index b346735..f0d8120 100644 (file)
--- a/Build.PL
+++ b/Build.PL
@@ -18,7 +18,7 @@ my $build = Module::Build->new(
         'HTTP::Request'                     => 0,
         'HTTP::Response'                    => 0,
         'LWP::UserAgent'                    => 0,
-        'Module::Pluggable::Fast'           => 0.15,
+        'Module::Pluggable::Fast'           => 0.16,
         'Path::Class'                       => 0,
         'Template'                          => 0,
         'Text::ASCIITable'                  => 0,
diff --git a/Changes b/Changes
index bc8d53c..2ad2bad 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,8 @@
 This file documents the revision history for Perl extension Catalyst.
 
+5.23  2005-00-00 00:00:00
+        - added support for non Catalyst::Base components to live in namespace.
+
 5.22  2005-05-26 14:24:00
         - Improved base locating in MP engines
         - Improved error messages in C::E::HTTP::Daemon
index be6fb6d..3f8efc2 100644 (file)
@@ -11,7 +11,7 @@ our $CATALYST_SCRIPT_GEN = 4;
 
 __PACKAGE__->mk_classdata($_) for qw/dispatcher engine log/;
 
-our $VERSION = '5.22';
+our $VERSION = '5.23';
 our @ISA;
 
 =head1 NAME
index 4c3fb70..dd38bea 100644 (file)
@@ -2,7 +2,6 @@ package Catalyst::Base;
 
 use strict;
 use base qw/Class::Data::Inheritable Class::Accessor::Fast/;
-use Catalyst::Utils;
 use NEXT;
 
 __PACKAGE__->mk_classdata($_) for qw/_attr_cache _action_cache _config/;
@@ -70,12 +69,11 @@ component loader with config() support and a process() method placeholder.
 
 sub new {
     my ( $self, $c ) = @_;
-    my $class     = ref $self || $self;
-    my $appname   = Catalyst::Utils::class2appclass($class);
-    my $suffix    = Catalyst::Utils::class2classsuffix($class);
-    my $appconfig = $appname->config->{$suffix} || {};
-    my $config    = { %{ $self->config }, %{$appconfig} };
-    return $self->NEXT::new($config);
+    # Temporary fix, some components does not pass context to constructor
+    my $arguments = ( ref( $_[-1] ) eq 'HASH' ) ? $_[-1] : {};
+
+    return $self->NEXT::new( { %{ $self->config }, %{ $arguments } } );
 }
 
 # remember to leave blank lines between the consecutive =item's
index 4bd49ca..4bd1a43 100644 (file)
@@ -347,7 +347,7 @@ Setup actions for a component.
 =cut
 
 sub setup_actions {
-    my ( $self, $comps ) = @_;
+    my $self = shift;
 
     # These are the core structures
     $self->actions(
@@ -362,9 +362,11 @@ sub setup_actions {
 
     # We use a tree
     $self->tree( Tree::Simple->new( 0, Tree::Simple->ROOT ) );
-
-    for my $comp (@$comps) {
-        $comp = ref $comp || $comp;
+    
+    for my $comp ( keys %{ $self->components } ) {
+    
+        # We only setup components that inherit from Catalyst::Base  
+        next unless $comp->isa('Catalyst::Base');
 
         for my $action ( @{ Catalyst::Utils::reflect_actions($comp) } ) {
             my ( $code, $attrs ) = @{$action};
@@ -400,6 +402,8 @@ sub setup_actions {
         }
 
     }
+    
+    return unless $self->debug;
 
     my $actions  = $self->actions;
     my $privates = Text::ASCIITable->new;
@@ -423,7 +427,7 @@ sub setup_actions {
 
     $walker->( $walker, $self->tree, '' );
     $self->log->debug( 'Loaded private actions', $privates->draw )
-      if ( @{ $privates->{tbl_rows} } && $self->debug );
+      if ( @{ $privates->{tbl_rows} } );
 
     my $publics = Text::ASCIITable->new;
     $publics->setCols( 'Public', 'Private' );
@@ -438,7 +442,7 @@ sub setup_actions {
     }
 
     $self->log->debug( 'Loaded public actions', $publics->draw )
-      if ( @{ $publics->{tbl_rows} } && $self->debug );
+      if ( @{ $publics->{tbl_rows} } );
 
     my $regexes = Text::ASCIITable->new;
     $regexes->setCols( 'Regex', 'Private' );
@@ -453,7 +457,7 @@ sub setup_actions {
     }
 
     $self->log->debug( 'Loaded regex actions', $regexes->draw )
-      if ( @{ $regexes->{tbl_rows} } && $self->debug );
+      if ( @{ $regexes->{tbl_rows} } );
 }
 
 =back
index 16136fc..3e7cfbd 100644 (file)
@@ -13,6 +13,7 @@ use Text::ASCIITable;
 use Catalyst::Request;
 use Catalyst::Request::Upload;
 use Catalyst::Response;
+use Catalyst::Utils;
 
 require Module::Pluggable::Fast;
 
@@ -659,7 +660,28 @@ Setup.
 
 sub setup {
     my $self = shift;
+
+    # Initialize our data structure
+    $self->components( {} );    
+
     $self->setup_components;
+
+    if ( $self->debug ) {
+        my $t = Text::ASCIITable->new;
+        $t->setOptions( 'hide_HeadRow', 1 );
+        $t->setOptions( 'hide_HeadLine', 1 );
+        $t->setCols('Class');
+        $t->setColWidth( 'Class', 75, 1 );
+        $t->addRow($_) for sort keys %{ $self->components };
+        $self->log->debug( 'Loaded components', $t->draw )
+          if ( @{ $t->{tbl_rows} } );
+    }
+    
+    # Add our self to components, since we are also a component
+    $self->components->{ $self } = $self;
+
+    $self->setup_actions;
+
     if ( $self->debug ) {
         my $name = $self->config->{name} || 'Application';
         $self->log->info("$name powered by Catalyst $Catalyst::VERSION");
@@ -675,38 +697,49 @@ Setup components.
 sub setup_components {
     my $self = shift;
     
-    # Components
-    my $class = ref $self || $self;
-    eval <<"";
-        package $class;
-        import Module::Pluggable::Fast
-          name   => '_components',
-          search => [
-            '$class\::Controller', '$class\::C',
-            '$class\::Model',      '$class\::M',
-            '$class\::View',       '$class\::V'
-          ];
+    my $callback = sub {
+        my ( $component, $context ) = @_;
+
+        unless ( $component->isa('Catalyst::Base') ) {
+            return $component;
+        }
+
+        my $suffix = Catalyst::Utils::class2classsuffix($component);
+        my $config = $self->config->{$suffix} || {};
+
+        my $instance;
+
+        eval { 
+            $instance = $component->new( $context, $config );
+        };
+
+        if ( $@ ) {
+            die qq/Couldn't instantiate component "$component", "$@"/;
+        }
+
+        return $instance;
+    };
+
+    eval {
+        Module::Pluggable::Fast->import(
+            name     => '_components',
+            search   => [
+                "$self\::Controller", "$self\::C",
+                "$self\::Model",      "$self\::M",
+                "$self\::View",       "$self\::V"
+            ],
+            callback => $callback
+        );
+    };
 
     if ( my $error = $@ ) {
         chomp $error;
         die qq/Couldn't load components "$error"/;
     }
 
-    $self->components( {} );
-    my @comps;
-    for my $comp ( $self->_components($self) ) {
-        $self->components->{ ref $comp } = $comp;
-        push @comps, $comp;
+    for my $component ( $self->_components($self) ) {
+        $self->components->{ ref $component || $component } = $component;
     }
-
-    my $t = Text::ASCIITable->new( { hide_HeadRow => 1, hide_HeadLine => 1 } );
-    $t->setCols('Class');
-    $t->setColWidth( 'Class', 75, 1 );
-    $t->addRow($_) for sort keys %{ $self->components };
-    $self->log->debug( 'Loaded components', $t->draw )
-      if ( @{ $t->{tbl_rows} } && $self->debug );
-
-    $self->setup_actions( [ $self, @comps ] );
 }
 
 =item $c->state
index e2f691f..27bda13 100644 (file)
@@ -144,13 +144,12 @@ Lookup the current users DNS hostname.
 sub hostname {
     my $self = shift;
 
-    if ( @_ ) {
-        $self->{hostname} = shift;
-        return $self->{hostname};
+    if ( @_ == 0 && not $self->{hostname} ) {
+         $self->{hostname} = gethostbyaddr( inet_aton( $self->address ), AF_INET );
     }
 
-    unless ( $self->{hostname} ) {
-         $self->{hostname} = gethostbyaddr( inet_aton( $self->address ), AF_INET );
+    if ( @_ == 1 ) {
+        $self->{hostname} = shift;
     }
 
     return $self->{hostname};