File Coverage

blib/lib/Test2/Util/Sub.pm
Criterion Covered Total %
statement 53 54 98.1
branch 14 18 77.7
condition 1 3 33.3
subroutine 13 13 100.0
pod 2 5 40.0
total 83 93 89.2


line stmt bran cond sub pod time code
1             package Test2::Util::Sub;
2 169     169   1230 use strict;
  169         339  
  169         5002  
3 169     169   917 use warnings;
  169         413  
  169         7353  
4              
5             our $VERSION = '0.000156';
6              
7 169     169   1007 use Carp qw/croak carp/;
  169         412  
  169         9114  
8 169     169   1514 use B();
  169         367  
  169         8999  
9              
10             our @EXPORT_OK = qw{
11             sub_info
12             sub_name
13              
14             gen_reader gen_writer gen_accessor
15             };
16 169     169   1067 use base 'Exporter';
  169         415  
  169         120402  
17              
18             sub gen_reader {
19 6     6 0 12 my $field = shift;
20 6     6   34 return sub { $_[0]->{$field} };
  6         30  
21             }
22              
23             sub gen_writer {
24 6     6 0 14 my $field = shift;
25 6     6   40 return sub { $_[0]->{$field} = $_[1] };
  6         25  
26             }
27              
28             sub gen_accessor {
29 9     9 0 19 my $field = shift;
30             return sub {
31 12     12   45 my $self = shift;
32 12 100       39 ($self->{$field}) = @_ if @_;
33 12         63 return $self->{$field};
34 9         56 };
35             }
36              
37             sub sub_name {
38 5     5 1 52 my ($sub) = @_;
39              
40 5 100       453 croak "sub_name requires a coderef as its only argument"
41             unless ref($sub) eq 'CODE';
42              
43 2         10 my $cobj = B::svref_2object($sub);
44 2         11 my $name = $cobj->GV->NAME;
45 2         16 return $name;
46             }
47              
48             sub sub_info {
49 1471     1471 1 7008 my ($sub, @all_lines) = @_;
50 1471         4762 my %in = map {$_ => 1} @all_lines;
  0         0  
51              
52 1471 50       3354 croak "sub_info requires a coderef as its first argument"
53             unless ref($sub) eq 'CODE';
54              
55 1471         5051 my $cobj = B::svref_2object($sub);
56 1471         6198 my $name = $cobj->GV->NAME;
57 1471         6362 my $file = $cobj->FILE;
58 1471         6045 my $package = $cobj->GV->STASH->NAME;
59              
60 1471         5414 my $op = $cobj->START;
61 1471         3990 while ($op) {
62 27803 100       65597 push @all_lines => $op->line if $op->can('line');
63 27803 100       53580 last unless $op->can('next');
64 26332         76606 $op = $op->next;
65             }
66              
67 1471         2438 my ($start, $end, @lines);
68 1471 50       3146 if (@all_lines) {
69 1471         3493 @all_lines = sort { $a <=> $b } @all_lines;
  4057         5448  
70 1471         2875 ($start, $end) = ($all_lines[0], $all_lines[-1]);
71              
72             # Adjust start and end for the most common case of a multi-line block with
73             # parens on the lines before and after.
74 1471 100       2728 if ($start < $end) {
75 430 50 33     2039 $start-- unless $start <= 1 || $in{$start};
76 430 50       1089 $end++ unless $in{$end};
77             }
78 1471         3595 @lines = ($start, $end);
79             }
80              
81             return {
82 1471         14069 ref => $sub,
83             cobj => $cobj,
84             name => $name,
85             file => $file,
86             package => $package,
87             start_line => $start,
88             end_line => $end,
89             all_lines => \@all_lines,
90             lines => \@lines,
91             };
92             }
93              
94             1;
95              
96             __END__