Updated Catalyst::Request and Catalyst::Response to have sensible defaults for attributes
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Stats.pm
index e47954f..daa5a0e 100644 (file)
@@ -1,86 +1,81 @@
 package Catalyst::Stats;
 
-use strict;
-use warnings;
+use Moose;
 use Time::HiRes qw/gettimeofday tv_interval/;
 use Text::SimpleTable ();
 use Tree::Simple qw/use_weak_refs/;
 use Tree::Simple::Visitor::FindByUID;
 
-sub new {
-    my $class = shift;
-
-    my $root = Tree::Simple->new({t => [gettimeofday]});
-    bless { 
-       enabled => 1,
-       stack => [ $root ],
-       tree => $root,
-    }, ref $class || $class;
-}
-
-sub enable {
-    my ($self, $enable) = @_;
-
-    $self->{enabled} = $enable;
-}
+has enable => (is => 'rw', required => 1, default => sub{ 1 });
+has tree => (
+             is => 'ro',
+             required => 1,
+             default => sub{ Tree::Simple->new({t => [gettimeofday]}) }
+            );
+has stack => (
+              is => 'ro',
+              required => 1,
+              lazy => 1,
+              default => sub { [ shift->tree ] }
+             );
 
 sub profile {
     my $self = shift;
 
-    return unless $self->{enabled};
+    return unless $self->enable;
 
     my %params;
     if (@_ <= 1) {
-       $params{comment} = shift || "";
+        $params{comment} = shift || "";
     }
     elsif (@_ % 2 != 0) {
-       die "profile() requires a single comment parameter or a list of name-value pairs; found " 
-           . (scalar @_) . " values: " . join(", ", @_);
+        die "profile() requires a single comment parameter or a list of name-value pairs; found "
+            . (scalar @_) . " values: " . join(", ", @_);
     }
     else {
-       (%params) = @_;
-       $params{comment} ||= "";
+        (%params) = @_;
+        $params{comment} ||= "";
     }
 
     my $parent;
     my $prev;
     my $t = [ gettimeofday ];
+    my $stack = $self->stack;
 
     if ($params{end}) {
-       # parent is on stack; search for matching block and splice out
-       for (my $i = $#{$self->{stack}}; $i > 0; $i--) {
-           if ($self->{stack}->[$i]->getNodeValue->{action} eq $params{end}) {
-               my $node = $self->{stack}->[$i];
-               splice(@{$self->{stack}}, $i, 1);
-               # Adjust elapsed on partner node
-               my $v = $node->getNodeValue;
-               $v->{elapsed} =  tv_interval($v->{t}, $t);
-               return $node->getUID;
-           }
-       }
-       # if partner not found, fall through to treat as non-closing call
+        # parent is on stack; search for matching block and splice out
+        for (my $i = $#{$stack}; $i > 0; $i--) {
+            if ($stack->[$i]->getNodeValue->{action} eq $params{end}) {
+                my ($node) = splice(@{$stack}, $i, 1);
+                # Adjust elapsed on partner node
+                my $v = $node->getNodeValue;
+                $v->{elapsed} =  tv_interval($v->{t}, $t);
+                return $node->getUID;
+            }
+        }
+    # if partner not found, fall through to treat as non-closing call
     }
     if ($params{parent}) {
-       # parent is explicitly defined
-       $prev = $parent = $self->_get_uid($params{parent}) or return undef;
+        # parent is explicitly defined
+        $prev = $parent = $self->_get_uid($params{parent});
     }
     if (!$parent) {
-       # Find previous node, which is either previous sibling or parent, for ref time.
-       $prev = $parent = $self->{stack}->[-1] or return undef;
-       my $n = $parent->getChildCount;
-       $prev = $parent->getChild($n - 1) if $n > 0;
+        # Find previous node, which is either previous sibling or parent, for ref time.
+        $prev = $parent = $stack->[-1] or return undef;
+        my $n = $parent->getChildCount;
+        $prev = $parent->getChild($n - 1) if $n > 0;
     }
 
     my $node = Tree::Simple->new({
-       action  => $params{begin} || "",
-       t => $t, 
-       elapsed => tv_interval($prev->getNodeValue->{t}, $t),
-       comment => $params{comment},
+        action  => $params{begin} || "",
+        t => $t,
+        elapsed => tv_interval($prev->getNodeValue->{t}, $t),
+        comment => $params{comment},
     });
     $node->setUID($params{uid}) if $params{uid};
 
     $parent->addChild($node);
-    push(@{$self->{stack}}, $node) if $params{begin};
+    push(@{$stack}, $node) if $params{begin};
 
     return $node->getUID;
 }
@@ -92,28 +87,27 @@ sub elapsed {
 sub report {
     my $self = shift;
 
-# close any remaining open nodes
-    for (my $i = $#{$self->{stack}}; $i > 0; $i--) {
-       $self->profile(end => $self->{stack}->[$i]->getNodeValue->{action});
-    }
+    # close any remaining open nodes
+    map { $self->profile(end => $_->getNodeValue->{action}) }
+      (reverse @{ $self->stack })[1 .. $#{$self->stack}];
 
     my $t = Text::SimpleTable->new( [ 62, 'Action' ], [ 9, 'Time' ] );
     my @results;
-    $self->{tree}->traverse(
-                           sub {
-                               my $action = shift;
-                               my $stat   = $action->getNodeValue;
-                               my @r = ( $action->getDepth,
-                                         ($stat->{action} || "") .
-                                         ($stat->{action} && $stat->{comment} ? " " : "") . ($stat->{comment} ? '- ' . $stat->{comment} : ""),
-                                         $stat->{elapsed},
-                                         $stat->{action} ? 1 : 0,
-                                         );
-                               $t->row( ( q{ } x $r[0] ) . $r[1], 
-                                        defined $r[2] ? sprintf("%fs", $r[2]) : '??');
-                               push(@results, \@r);
-                           }
-                           );
+    $self->tree->traverse(
+                sub {
+                my $action = shift;
+                my $stat   = $action->getNodeValue;
+                my @r = ( $action->getDepth,
+                      ($stat->{action} || "") .
+                      ($stat->{action} && $stat->{comment} ? " " : "") . ($stat->{comment} ? '- ' . $stat->{comment} : ""),
+                      $stat->{elapsed},
+                      $stat->{action} ? 1 : 0,
+                      );
+                $t->row( ( q{ } x $r[0] ) . $r[1],
+                     defined $r[2] ? sprintf("%fs", $r[2]) : '??');
+                push(@results, \@r);
+                }
+            );
     return wantarray ? @results : $t->draw;
 }
 
@@ -122,10 +116,13 @@ sub _get_uid {
 
     my $visitor = Tree::Simple::Visitor::FindByUID->new;
     $visitor->searchForUID($uid);
-    $self->{tree}->accept($visitor);
+    $self->tree->accept($visitor);
     return $visitor->getResult;
 } 
 
+no Moose;
+__PACKAGE__->meta->make_immutable();
+
 1;
 
 __END__
@@ -309,4 +306,6 @@ it under the same terms as Perl itself.
 
 =cut
 
+__PACKAGE__->meta->make_immutable;
+
 1;