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 168     168   1102 use strict;
  168         291  
  168         4432  
3 168     168   773 use warnings;
  168         369  
  168         6636  
4              
5             our $VERSION = '0.000153';
6              
7 168     168   998 use Carp qw/croak carp/;
  168         345  
  168         7863  
8 168     168   1093 use B();
  168         494  
  168         7769  
9              
10             our @EXPORT_OK = qw{
11             sub_info
12             sub_name
13              
14             gen_reader gen_writer gen_accessor
15             };
16 168     168   1075 use base 'Exporter';
  168         388  
  168         106493  
17              
18             sub gen_reader {
19 6     6 0 11 my $field = shift;
20 6     6   50 return sub { $_[0]->{$field} };
  6         28  
21             }
22              
23             sub gen_writer {
24 6     6 0 9 my $field = shift;
25 6     6   37 return sub { $_[0]->{$field} = $_[1] };
  6         31  
26             }
27              
28             sub gen_accessor {
29 9     9 0 18 my $field = shift;
30             return sub {
31 12     12   32 my $self = shift;
32 12 100       41 ($self->{$field}) = @_ if @_;
33 12         80 return $self->{$field};
34 9         47 };
35             }
36              
37             sub sub_name {
38 5     5 1 41 my ($sub) = @_;
39              
40 5 100       452 croak "sub_name requires a coderef as its only argument"
41             unless ref($sub) eq 'CODE';
42              
43 2         11 my $cobj = B::svref_2object($sub);
44 2         16 my $name = $cobj->GV->NAME;
45 2         27 return $name;
46             }
47              
48             sub sub_info {
49 1469     1469 1 9658 my ($sub, @all_lines) = @_;
50 1469         2784 my %in = map {$_ => 1} @all_lines;
  0         0  
51              
52 1469 50       5485 croak "sub_info requires a coderef as its first argument"
53             unless ref($sub) eq 'CODE';
54              
55 1469         5513 my $cobj = B::svref_2object($sub);
56 1469         6936 my $name = $cobj->GV->NAME;
57 1469         6546 my $file = $cobj->FILE;
58 1469         5567 my $package = $cobj->GV->STASH->NAME;
59              
60 1469         6115 my $op = $cobj->START;
61 1469         3939 while ($op) {
62 27775 100       71465 push @all_lines => $op->line if $op->can('line');
63 27775 100       57307 last unless $op->can('next');
64 26306         78597 $op = $op->next;
65             }
66              
67 1469         2589 my ($start, $end, @lines);
68 1469 50       3177 if (@all_lines) {
69 1469         3943 @all_lines = sort { $a <=> $b } @all_lines;
  4055         5947  
70 1469         3120 ($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 1469 100       3162 if ($start < $end) {
75 430 50 33     2545 $start-- unless $start <= 1 || $in{$start};
76 430 50       1111 $end++ unless $in{$end};
77             }
78 1469         3534 @lines = ($start, $end);
79             }
80              
81             return {
82 1469         15536 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__