/usr/local/CPAN/Devel-Profit/Devel/Profit/Cmd/Command/SubroutineLine.pm
package Devel::Profit::Cmd::Command::SubroutineLine;
use strict;
use warnings;
use IO::File;
use PPI;
use PPIx::LineToSub;
use Moose;
extends qw(Devel::Profit::Cmd::Command MooseX::App::Cmd::Command);
has filename => (
isa => "Str",
is => "rw",
cmd_aliases => "file",
documentation => "read from a specific filename",
);
sub command_names {
return ( 'subroutine_line', 'sub_line' );
}
sub usage_desc {
my $self = shift;
return "devel_profit subroutine_line [--filename other.out]";
}
sub abstract {
my $self = shift;
return 'Profile by package, subroutine and line';
}
sub run {
my ( $self, $opt, $args ) = @_;
my $filename = $self->filename || 'profit.out';
my $fh = IO::File->new('profit.out') || die "Could not open profit.out";
my $line = <$fh>;
my %usecs;
my $totusecs;
my %file;
printf( "%s %s\n", '%Time', 'Filename' );
while ( my $row = <$fh> ) {
if ( my ( $file_number, $file, $usecs ) = $row =~ /^(\d+)=(.*)$/ ) {
$file{$file_number} = $file;
} else {
my ( $file_number, $line, $usecs )
= $row =~ /^(\d+):(\d+) (\d+)$/;
my $file = $file{$file_number};
my $document = get_document($file);
next unless $document;
my ( $package, $sub ) = $document->line_to_sub($line);
$usecs{ $package . '::' . $sub . ':' . $line } += $usecs;
$totusecs += $usecs;
}
}
$self->show( \%usecs, $totusecs );
}
my %cache;
sub get_document {
my ($file) = @_;
if ( $cache{$file} ) {
return $cache{$file};
}
my $document = PPI::Document->new($file);
return unless $document;
$document->index_line_to_sub;
$cache{$file} = $document;
return $document;
}
1;