Author: tim.bunce
Date: Wed Nov 12 04:38:10 2008
New Revision: 594

Added:
    trunk/lib/Devel/NYTProf/FileInfo.pm
    trunk/lib/Devel/NYTProf/SubInfo.pm
Modified:
    trunk/MANIFEST
    trunk/NYTProf.xs
    trunk/lib/Devel/NYTProf/Data.pm

Log:
Move ::ProfFile class out to new ::FileInfo class.
Move ::ProfSub class out to new ::SubInfo class.
Add Devel::NYTProf::Constants module
Add constants for elements of FileInfo array.


Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST      (original)
+++ trunk/MANIFEST      Wed Nov 12 04:38:10 2008
@@ -17,9 +17,12 @@
  lib/Devel/NYTProf.pm
  lib/Devel/NYTProf/Apache.pm
  lib/Devel/NYTProf/Core.pm
+lib/Devel/NYTProf/Constants.pm
  lib/Devel/NYTProf/Data.pm
+lib/Devel/NYTProf/FileInfo.pm
  lib/Devel/NYTProf/Reader.pm
  lib/Devel/NYTProf/ReadStream.pm
+lib/Devel/NYTProf/SubInfo.pm
  lib/Devel/NYTProf/Test.pm
  lib/Devel/NYTProf/Util.pm
  lib/Devel/NYTProf/js/jquery.min.js

Modified: trunk/NYTProf.xs
==============================================================================
--- trunk/NYTProf.xs    (original)
+++ trunk/NYTProf.xs    Wed Nov 12 04:38:10 2008
@@ -84,9 +84,20 @@
  #define NYTP_TAG_STRING          '\''
  #define NYTP_TAG_STRING_UTF8     '"'
  #define NYTP_TAG_START_DEFLATE   'z'
-
  #define NYTP_TAG_NO_TAG          '\0'   /* Used as a flag to mean "no tag"  
*/

+/* indices to elements of the file info array */
+#define NYTP_FIDi_FILENAME      0
+#define NYTP_FIDi_EVAL_FID      1
+#define NYTP_FIDi_EVAL_LINE     2
+#define NYTP_FIDi_FID           3
+#define NYTP_FIDi_FLAGS         4
+#define NYTP_FIDi_FILESIZE      5
+#define NYTP_FIDi_FILEMTIME     6
+#define NYTP_FIDi_PROFILE       7
+#define NYTP_FIDi_EVAL_FI       8
+#define NYTP_FIDi_SUBS_DEFN     9
+

  /* Hash table definitions */
  #define MAX_HASH_SIZE 512
@@ -2987,14 +2998,16 @@
                   */
                  av = newAV();
                  /* drop newline */
-                av_store(av, 0, filename_sv); /* av now owns the sv */
-                av_store(av, 1, (eval_file_num) ? newSVuv(eval_file_num) :  
&PL_sv_no);
-                av_store(av, 2, (eval_file_num) ? newSVuv(eval_line_num) :  
&PL_sv_no);
-                av_store(av, 3, newSVuv(file_num));
-                av_store(av, 4, newSVuv(fid_flags));
-                av_store(av, 5, newSVuv(file_size));
-                av_store(av, 6, newSVuv(file_mtime));
-                /* 7: profile ref */
+                av_store(av, NYTP_FIDi_FILENAME, filename_sv); /* av now  
owns the sv */
+                av_store(av, NYTP_FIDi_EVAL_FID,  (eval_file_num) ?  
newSVuv(eval_file_num) : &PL_sv_no);
+                av_store(av, NYTP_FIDi_EVAL_LINE, (eval_file_num) ?  
newSVuv(eval_line_num) : &PL_sv_no);
+                av_store(av, NYTP_FIDi_FID,       newSVuv(file_num));
+                av_store(av, NYTP_FIDi_FLAGS,     newSVuv(fid_flags));
+                av_store(av, NYTP_FIDi_FILESIZE,  newSVuv(file_size));
+                av_store(av, NYTP_FIDi_FILEMTIME, newSVuv(file_mtime));
+                av_store(av, NYTP_FIDi_PROFILE,   &PL_sv_undef);
+                av_store(av, NYTP_FIDi_EVAL_FI,   &PL_sv_undef);
+                av_store(av, NYTP_FIDi_SUBS_DEFN, &PL_sv_undef);

                  av_store(fid_fileinfo_av, file_num, newRV_noinc((SV*)av));
                  break;
@@ -3069,11 +3082,11 @@
                  sv_setuv(*av_fetch(av, 0, 1), fid);
                  sv_setuv(*av_fetch(av, 1, 1), first_line);
                  sv_setuv(*av_fetch(av, 2, 1), last_line);
-                sv_setuv(*av_fetch(av, 3, 1),   0); /* cal count */
+                sv_setuv(*av_fetch(av, 3, 1),   0); /* call count */
                  sv_setnv(*av_fetch(av, 4, 1), 0.0); /* incl_time */
                  sv_setnv(*av_fetch(av, 5, 1), 0.0); /* excl_time */
                  sv_setsv(*av_fetch(av, 6, 1), subname_sv);
-                sv_setsv(*av_fetch(av, 6, 1), &PL_sv_undef); /* ref to  
profile */
+                sv_setsv(*av_fetch(av, 7, 1), &PL_sv_undef); /* ref to  
profile */
                  sv_setuv(*av_fetch(av, 8, 1),   0); /* rec_depth */
                  sv_setnv(*av_fetch(av, 9, 1), 0.0); /* reci_time */
                  break;
@@ -3409,19 +3422,26 @@
   * Perl XS Code Below Here         *
   ***********************************/

-MODULE = Devel::NYTProf     PACKAGE = Devel::NYTProf
+MODULE = Devel::NYTProf     PACKAGE = Devel::NYTProf::Constants

  PROTOTYPES: DISABLE

-I32
-constant()
-    PROTOTYPE:
-    ALIAS:
-        NYTP_FIDf_IS_PMC = NYTP_FIDf_IS_PMC
-    CODE:
-    RETVAL = ix;
-    OUTPUT:
-    RETVAL
+BOOT:
+    {
+    HV *stash = gv_stashpv("Devel::NYTProf::Constants", GV_ADDWARN);
+    newCONSTSUB(stash, "NYTP_FIDf_IS_PMC", newSViv(NYTP_FIDf_IS_PMC));
+    /* NYTP_FIDi_* */
+    newCONSTSUB(stash, "NYTP_FIDi_FILENAME",  newSViv(NYTP_FIDi_FILENAME));
+    newCONSTSUB(stash, "NYTP_FIDi_EVAL_FID",  newSViv(NYTP_FIDi_EVAL_FID));
+    newCONSTSUB(stash, "NYTP_FIDi_EVAL_LINE",  
newSViv(NYTP_FIDi_EVAL_LINE));
+    newCONSTSUB(stash, "NYTP_FIDi_FID",       newSViv(NYTP_FIDi_FID));
+    newCONSTSUB(stash, "NYTP_FIDi_FLAGS",     newSViv(NYTP_FIDi_FLAGS));
+    newCONSTSUB(stash, "NYTP_FIDi_FILESIZE",  newSViv(NYTP_FIDi_FILESIZE));
+    newCONSTSUB(stash, "NYTP_FIDi_FILEMTIME",  
newSViv(NYTP_FIDi_FILEMTIME));
+    newCONSTSUB(stash, "NYTP_FIDi_PROFILE",   newSViv(NYTP_FIDi_PROFILE));
+    newCONSTSUB(stash, "NYTP_FIDi_EVAL_FI",   newSViv(NYTP_FIDi_EVAL_FI));
+    newCONSTSUB(stash, "NYTP_FIDi_SUBS_DEFN",  
newSViv(NYTP_FIDi_SUBS_DEFN));
+    }


  MODULE = Devel::NYTProf     PACKAGE = Devel::NYTProf::Test

Modified: trunk/lib/Devel/NYTProf/Data.pm
==============================================================================
--- trunk/lib/Devel/NYTProf/Data.pm     (original)
+++ trunk/lib/Devel/NYTProf/Data.pm     Wed Nov 12 04:38:10 2008
@@ -48,6 +48,8 @@
  use Scalar::Util qw(blessed);

  use Devel::NYTProf::Core;
+use Devel::NYTProf::FileInfo;
+use Devel::NYTProf::SubInfo;
  use Devel::NYTProf::Util qw(strip_prefix_from_paths  
get_abs_paths_alternation_regex);

  our $VERSION = '2.07';
@@ -86,18 +88,18 @@
      $_->[7] = $profile for values %$sub_subinfo;

      # bless fid_fileinfo data
-    (my $fid_class = $class) =~ s/\w+$/ProfFile/;
+    (my $fid_class = $class) =~ s/\w+$/FileInfo/;
      $_ and bless $_ => $fid_class for @$fid_fileinfo;

      # bless sub_subinfo data
-    (my $sub_class = $class) =~ s/\w+$/ProfSub/;
+    (my $sub_class = $class) =~ s/\w+$/SubInfo/;
      $_ and bless $_ => $sub_class for values %$sub_subinfo;

      #$profile->_migrate_sub_callers_from_eval_fids;

      # XXX merge evals - should become a method optionally called here
      # (which uses other methods to do the work and those methods
-    # should also be called by Devel::NYTProf::ProfSub::callers())
+    # should also be called by Devel::NYTProf::SubInfo::callers())
      my %anon_eval_subs_merged;
      while (my ($subname, $subinfo) = each %$sub_subinfo) {

@@ -199,8 +201,8 @@
          return undef;
      }

-    # check if already a ProfFile object
-    return $arg if ref $arg and $arg->isa('Devel::NYTProf::ProfFile');
+    # check if already a file info object
+    return $arg if ref $arg and $arg->isa('Devel::NYTProf::FileInfo');

      my $fid = $self->resolve_fid($arg);
      if (not $fid) {
@@ -711,7 +713,7 @@
  Returns undef if the profile contains no C<sub_subinfo> data for the $file.

  The keys of the returned hash are fully qualified subroutine names and the
-corresponding value is a hash reference containing  
L<Devel::NYTProf::ProfSub>
+corresponding value is a hash reference containing  
L<Devel::NYTProf::SubInfo>
  objects.

  If $include_lines is true then the hash also contains integer keys
@@ -990,221 +992,6 @@
      require Data::Dumper;
      return Data::Dumper::Dumper(@_);
  }
-
-## --- will move out to separate files later ---
-# for now these are viewed as private classes
-
-{
-
-    package Devel::NYTProf::ProfFile;    # fid_fileinfo
-
-    use Devel::NYTProf::Util qw(strip_prefix_from_paths);
-
-    sub filename  { shift->[0] }
-    sub eval_fid  { shift->[1] }
-    sub eval_line { shift->[2] }
-    sub fid       { shift->[3] }
-    sub flags     { shift->[4] }
-    sub size      { shift->[5] }
-    sub mtime     { shift->[6] }
-    sub profile   { shift->[7] }
-
-    # if fid is an eval then return fileinfo obj for the fid that executed  
the eval
-    sub eval_fi   { $_[0]->[8] ||=  
$_[0]->profile->fileinfo_of($_[0]->eval_fid || return) }
-    # return a ref to a hash of { subname => subinfo, ... }
-    sub subs      { $_[0]->[9] ||= $_[0]->profile->fid_subs_map->{  
$_[0]->fid } }
-
-    sub line_time_data {
-        my ($self, $levels) = @_;
-        $levels ||= [ 'line' ];
-        # XXX this can be optimized once the fidinfo contains directs refs  
to the data
-        my $profile = $self->profile;
-        my $fid = $self->fid;
-        for my $level (@$levels) {
-            my $line_data = $profile->get_fid_line_data($level)->[$fid];
-            return $line_data if $line_data;
-        }
-        return undef;
-    }
-
-    sub excl_time { # total exclusive time for fid
-        my $self = shift;
-        my $line_data = $self->line_time_data([qw(sub block line)])
-            || return undef;
-        my $excl_time = 0;
-        for (@$line_data) {
-            next unless $_;
-            $excl_time += $_->[0];
-            if (my $eval_lines = $_->[2]) {
-                # line contains a string eval
-                $excl_time += $_->[0] for values %$eval_lines;
-            }
-        }
-        return $excl_time;
-    }
-
-    sub outer {
-        my ($self, $recurse) = @_;
-        my $fi  = $self->eval_fi
-            or return;
-        my $prev = $self;
-
-        while ($recurse and my $eval_fi = $fi->eval_fi) {
-            $prev = $fi;
-            $fi = $eval_fi;
-       }
-        return $fi unless wantarray;
-        return ($fi, $prev->eval_line);
-    }
-
-
-    sub is_pmc {
-        return (shift->flags & 1);    # NYTP_FIDf_IS_PMC
-    }
-
-
-    # should return the filename that the application used
-    # when loading the file
-    sub filename_without_inc {
-        my $self = shift;
-        my $f    = [$self->filename];
-        strip_prefix_from_paths([$self->profile->inc], $f);
-        return $f->[0];
-    }
-
-    sub _values_for_dump {
-        my $self   = shift;
-        my @values = @$self;
-        $values[0] = $self->filename_without_inc;
-        pop @values;    # remove profile ref
-        return [EMAIL PROTECTED];
-    }
-
-    sub delete_subs_called_info {
-        my $self = shift;
-        my $profile = $self->profile;
-        my $sub_caller = $profile->{sub_caller}
-            or return;
-        my $fid = $self->fid;
-        # remove sub_caller info for calls made *from within* this file
-        delete $_->{$fid} for values %$sub_caller;
-        return;
-    }
-
-    sub srclines_array {
-        my $self = shift;
-        my $profile = $self->profile;
-        #warn Dumper($profile->{fid_srclines});
-        my $fid = $self->fid;
-        if (my $srclines = $profile->{fid_srclines}[ $fid ]) {
-            my $copy = [ @$srclines ]; # shallow clone
-            shift @$copy; # line 0 not used
-            return $copy;
-        }
-        # open file
-        my $filename = $self->filename;
-        # if it's a .pmc then assume that's the file we want to look at
-        # (because the main use for .pmc's are related to perl6)
-        $filename .= "c" if $self->is_pmc;
-        open my $fh, "<", $filename
-            or return undef;
-        return [ <$fh> ];
-    }
-
-}    # end of package
-
-
-{
-
-    package Devel::NYTProf::ProfSub;    # sub_subinfo
-
-    use List::Util qw(sum);
-
-    sub fid        { $_[0]->[0] ||=  
$_[0]->profile->package_fids($_[0]->package) }
-    sub first_line { shift->[1] }
-    sub last_line  { shift->[2] }
-    sub calls      { shift->[3] }
-    sub incl_time  { shift->[4] }
-    sub excl_time  { shift->[5] }
-    sub subname    { shift->[6] }
-    sub profile    { shift->[7] }
-    sub package    { (my $pkg = shift->subname) =~ s/::.*?$//; return $pkg  
}
-    sub recur_max_depth { shift->[8] }
-    sub recur_incl_time { shift->[9] }
-
-    sub is_xsub {
-        my $self = shift;
-
-        # XXX should test == 0 but some xsubs still have undef first_line  
etc
-        return (!$self->first_line && !$self->last_line);
-    }
-
-    sub fileinfo {
-        my $self = shift;
-        my $fid  = $self->fid;
-        if (!$fid) {
-            return undef;    # sub not have a known fid
-        }
-        $self->profile->fileinfo_of($fid);
-    }
-
-    sub merge_in {
-        my $self    = shift;
-        my $newinfo = shift;
-        $self->[3] += $newinfo->[3];    # calls
-        $self->[4] += $newinfo->[4];    # calls
-        return;
-    }
-
-    sub _values_for_dump {
-        my $self   = shift;
-        my @values = @{$self}[0 .. 5, 8, 9 ];
-        return [EMAIL PROTECTED];
-    }
-
-    sub callers {
-        my $self = shift;
-
-        # { fid => { line => [ count, incl_time ] } } }
-        my $callers = $self->profile->{sub_caller}->{$self->subname}
-            or return undef;
-
-        # XXX should 'collapse' data for calls from eval fids
-        # (with an option to not collapse)
-        return $callers;
-    }
-
-    sub caller_fids {
-        my ($self, $merge_evals) = @_;
-        my $callers = $self->callers($merge_evals) || {};
-        my @fids = keys %$callers;
-        return @fids;    # count in scalar context
-    }
-
-    sub caller_count {
-        my ($self, $merge_evals) = @_;
-        my $callers = $self->callers($merge_evals) || {};
-
-        # count of the number of distinct locations sub is called from
-        return sum(map { scalar keys %$_ } values %$callers);
-    }
-
-    sub caller_places {
-        my ($self, $merge_evals) = @_;
-        my $callers = $self->callers
-            or return 0;
-
-        # scalar: count of the number of distinct locations sub is called  
from
-        # list: array of [ fid, line, @... ]
-        my @callers;
-        warn "caller_places in list context not implemented/tested yet";
-        while (my ($fid, $lines) = each %$callers) {
-            push @callers, map { [$fid, $_, @{$lines->{$_}}] }  
keys %$lines;
-        }
-        return [EMAIL PROTECTED];
-    }
-
-}    # end of package

  1;


Added: trunk/lib/Devel/NYTProf/FileInfo.pm
==============================================================================
--- (empty file)
+++ trunk/lib/Devel/NYTProf/FileInfo.pm Wed Nov 12 04:38:10 2008
@@ -0,0 +1,126 @@
+package Devel::NYTProf::FileInfo;    # fid_fileinfo
+
+use strict;
+
+use Devel::NYTProf::Util qw(strip_prefix_from_paths);
+
+use Devel::NYTProf::Constants qw(
+    NYTP_FIDi_FILENAME NYTP_FIDi_EVAL_FID NYTP_FIDi_EVAL_LINE NYTP_FIDi_FID
+    NYTP_FIDi_FLAGS NYTP_FIDi_FILESIZE NYTP_FIDi_FILEMTIME  
NYTP_FIDi_PROFILE
+    NYTP_FIDi_EVAL_FI NYTP_FIDi_SUBS_DEFN
+);
+
+sub filename  { shift->[NYTP_FIDi_FILENAME()] }
+sub eval_fid  { shift->[NYTP_FIDi_EVAL_FID()] }
+sub eval_line { shift->[NYTP_FIDi_EVAL_LINE()] }
+sub fid       { shift->[NYTP_FIDi_FID()] }
+sub flags     { shift->[NYTP_FIDi_FLAGS()] }
+sub size      { shift->[NYTP_FIDi_FILESIZE()] }
+sub mtime     { shift->[NYTP_FIDi_FILEMTIME()] }
+sub profile   { shift->[NYTP_FIDi_PROFILE()] }
+
+# if fid is an eval then return fileinfo obj for the fid that executed the  
eval
+sub eval_fi   { $_[0]->[NYTP_FIDi_EVAL_FI()] ||=  
$_[0]->profile->fileinfo_of($_[0]->eval_fid || return) }
+# return a ref to a hash of { subname => subinfo, ... }
+sub subs      { $_[0]->[NYTP_FIDi_SUBS_DEFN()] ||=  
$_[0]->profile->fid_subs_map->{ $_[0]->fid } }
+
+sub _values_for_dump {
+    my $self   = shift;
+    my @values = @{$self}[
+        NYTP_FIDi_FILENAME, NYTP_FIDi_EVAL_FID, NYTP_FIDi_EVAL_LINE,  
NYTP_FIDi_FID,
+        NYTP_FIDi_FLAGS, NYTP_FIDi_FILESIZE, NYTP_FIDi_FILEMTIME
+    ];
+    $values[0] = $self->filename_without_inc;
+    return [EMAIL PROTECTED];
+}
+
+sub line_time_data {
+    my ($self, $levels) = @_;
+    $levels ||= [ 'line' ];
+    # XXX this can be optimized once the fidinfo contains directs refs to  
the data
+    my $profile = $self->profile;
+    my $fid = $self->fid;
+    for my $level (@$levels) {
+        my $line_data = $profile->get_fid_line_data($level)->[$fid];
+        return $line_data if $line_data;
+    }
+    return undef;
+}
+
+sub excl_time { # total exclusive time for fid
+    my $self = shift;
+    my $line_data = $self->line_time_data([qw(sub block line)])
+        || return undef;
+    my $excl_time = 0;
+    for (@$line_data) {
+        next unless $_;
+        $excl_time += $_->[0];
+        if (my $eval_lines = $_->[2]) {
+            # line contains a string eval
+            $excl_time += $_->[0] for values %$eval_lines;
+        }
+    }
+    return $excl_time;
+}
+
+sub outer {
+    my ($self, $recurse) = @_;
+    my $fi  = $self->eval_fi
+        or return;
+    my $prev = $self;
+
+    while ($recurse and my $eval_fi = $fi->eval_fi) {
+        $prev = $fi;
+        $fi = $eval_fi;
+    }
+    return $fi unless wantarray;
+    return ($fi, $prev->eval_line);
+}
+
+
+sub is_pmc {
+    return (shift->flags & 1);    # NYTP_FIDf_IS_PMC
+}
+
+
+# should return the filename that the application used
+# when loading the file
+sub filename_without_inc {
+    my $self = shift;
+    my $f    = [$self->filename];
+    strip_prefix_from_paths([$self->profile->inc], $f);
+    return $f->[0];
+}
+
+sub delete_subs_called_info {
+    my $self = shift;
+    my $profile = $self->profile;
+    my $sub_caller = $profile->{sub_caller}
+        or return;
+    my $fid = $self->fid;
+    # remove sub_caller info for calls made *from within* this file
+    delete $_->{$fid} for values %$sub_caller;
+    return;
+}
+
+sub srclines_array {
+    my $self = shift;
+    my $profile = $self->profile;
+    #warn Dumper($profile->{fid_srclines});
+    my $fid = $self->fid;
+    if (my $srclines = $profile->{fid_srclines}[ $fid ]) {
+        my $copy = [ @$srclines ]; # shallow clone
+        shift @$copy; # line 0 not used
+        return $copy;
+    }
+    # open file
+    my $filename = $self->filename;
+    # if it's a .pmc then assume that's the file we want to look at
+    # (because the main use for .pmc's are related to perl6)
+    $filename .= "c" if $self->is_pmc;
+    open my $fh, "<", $filename
+        or return undef;
+    return [ <$fh> ];
+}
+
+1;

Added: trunk/lib/Devel/NYTProf/SubInfo.pm
==============================================================================
--- (empty file)
+++ trunk/lib/Devel/NYTProf/SubInfo.pm  Wed Nov 12 04:38:10 2008
@@ -0,0 +1,89 @@
+package Devel::NYTProf::SubInfo;    # sub_subinfo
+
+use List::Util qw(sum);
+
+sub fid        { $_[0]->[0] ||=  
$_[0]->profile->package_fids($_[0]->package) }
+sub first_line { shift->[1] }
+sub last_line  { shift->[2] }
+sub calls      { shift->[3] }
+sub incl_time  { shift->[4] }
+sub excl_time  { shift->[5] }
+sub subname    { shift->[6] }
+sub profile    { shift->[7] }
+sub package    { (my $pkg = shift->subname) =~ s/::.*?$//; return $pkg }
+sub recur_max_depth { shift->[8] }
+sub recur_incl_time { shift->[9] }
+
+sub is_xsub {
+    my $self = shift;
+
+    # XXX should test == 0 but some xsubs still have undef first_line etc
+    return (!$self->first_line && !$self->last_line);
+}
+
+sub fileinfo {
+    my $self = shift;
+    my $fid  = $self->fid;
+    if (!$fid) {
+        return undef;    # sub not have a known fid
+    }
+    $self->profile->fileinfo_of($fid);
+}
+
+sub merge_in {
+    my $self    = shift;
+    my $newinfo = shift;
+    $self->[3] += $newinfo->[3];    # calls
+    $self->[4] += $newinfo->[4];    # calls
+    return;
+}
+
+sub _values_for_dump {
+    my $self   = shift;
+    my @values = @{$self}[0 .. 5, 8, 9 ];
+    return [EMAIL PROTECTED];
+}
+
+sub callers {
+    my $self = shift;
+
+    # { fid => { line => [ count, incl_time ] } }
+    my $callers = $self->profile->{sub_caller}->{$self->subname}
+        or return undef;
+
+    # XXX should 'collapse' data for calls from eval fids
+    # (with an option to not collapse)
+    return $callers;
+}
+
+sub caller_fids {
+    my ($self, $merge_evals) = @_;
+    my $callers = $self->callers($merge_evals) || {};
+    my @fids = keys %$callers;
+    return @fids;    # count in scalar context
+}
+
+sub caller_count {
+    my ($self, $merge_evals) = @_;
+    my $callers = $self->callers($merge_evals) || {};
+
+    # count of the number of distinct locations sub is called from
+    return sum(map { scalar keys %$_ } values %$callers);
+}
+
+sub caller_places {
+    my ($self, $merge_evals) = @_;
+    my $callers = $self->callers
+        or return 0;
+
+    # scalar: count of the number of distinct locations sub is called from
+    # list: array of [ fid, line, @... ]
+    my @callers;
+    warn "caller_places in list context not implemented/tested yet";
+    while (my ($fid, $lines) = each %$callers) {
+        push @callers, map { [$fid, $_, @{$lines->{$_}}] } keys %$lines;
+    }
+    return [EMAIL PROTECTED];
+}
+
+1;

--~--~---------~--~----~------------~-------~--~----~
You've received this message because you are subscribed to
the Devel::NYTProf Development User group.

Group hosted at:  http://groups.google.com/group/develnytprof-dev
Project hosted at:  http://perl-devel-nytprof.googlecode.com
CPAN distribution:  http://search.cpan.org/dist/Devel-NYTProf

To post, email:  [email protected]
To unsubscribe, email:  [EMAIL PROTECTED]
-~----------~----~----~----~------~----~------~--~---

Reply via email to