File Coverage

blib/lib/Devel/Chitin/Location.pm
Criterion Covered Total %
statement 48 62 77.4
branch 5 12 41.6
condition 0 3 0.0
subroutine 12 14 85.7
pod 1 3 33.3
total 66 94 70.2


line stmt bran cond sub pod time code
1             package Devel::Chitin::Location;
2              
3 35     35   706 use strict;
  35         66  
  35         1022  
4 35     35   183 use warnings;
  35         67  
  35         1703  
5              
6             our $VERSION = '0.15';
7              
8 35     35   191 use Carp;
  35         61  
  35         18651  
9              
10             sub new {
11 394     394 0 325507 my $class = shift;
12 394         3389 my %props = @_;
13              
14 394         1629 my @props = $class->_required_properties;
15 394         1169 foreach my $prop ( @props ) {
16 1576 50       3633 unless (exists $props{$prop}) {
17 0         0 Carp::croak("$prop is a required property");
18             }
19             }
20              
21 394         1109 my $self = bless \%props, $class;
22 394         2170 return $self;
23             }
24              
25             sub _required_properties {
26 497     497   2197 qw( package filename line subroutine );
27             }
28              
29             sub _optional_properties {
30 103     103   272 qw( callsite );
31             }
32              
33             sub at_end {
34 0     0 1 0 my $self = shift;
35 0   0     0 return (($self->package eq 'Devel::Chitin::exiting')
36             &&
37             ($self->subroutine eq 'Devel::Chitin::exiting::at_exit'));
38             }
39              
40             sub current {
41 0     0 0 0 my $class = shift;
42 0         0 my %props = @_;
43              
44 0         0 for (my $i = 0; ; $i++) {
45 0         0 my @caller = caller($i);
46 0 0       0 last unless @caller;
47 0 0       0 if ($caller[3] eq 'DB::DB') {
48 0         0 @props{'package','filename','line'} = @caller[0,1,2];
49 0         0 $props{subroutine} = (caller($i+1))[3];
50 0         0 $props{callsite} = get_callsite($i);
51 0         0 last;
52             }
53             }
54 0         0 return $class->new(%props);
55             }
56              
57             sub _make_accessors {
58 69     69   196 my $package = shift;
59 69         166 my @accessor_names;
60 69         264 @accessor_names = ( $package->_required_properties, $package->_optional_properties );
61 69 100       292 if ($package ne __PACKAGE__) {
62             # called as a class method by a subclass
63 34         92 my %base_class_accessors = map { $_ => 1 } (_required_properties(), _optional_properties());
  170         401  
64 34         115 @accessor_names = grep { ! $base_class_accessors{$_} } @accessor_names;
  204         500  
65             }
66            
67 69         179 foreach my $acc ( @accessor_names ) {
68 209     1645   685 my $sub = sub { return shift->{$acc} };
  1645         5096  
69 209         486 my $subname = "${package}::${acc}";
70 35     35   290 no strict 'refs';
  35         101  
  35         5841  
71 209         313 *{$subname} = $sub;
  209         2234  
72             }
73             }
74              
75             sub get_callsite { undef }
76              
77             BEGIN {
78 35     35   294 __PACKAGE__->_make_accessors();
79              
80 35         62 local $@;
81 35 50       107 my $site = eval { require Devel::Callsite && Devel::Callsite::callsite() };
  35         16717  
82 35 50       25204 if ($site) {
83 35         112 my $get_callsite_name = join('::', __PACKAGE__, 'get_callsite');
84 35     35   289 no strict 'refs';
  35         72  
  35         1330  
85 35     35   296 no warnings 'redefine';
  35         130  
  35         2341  
86 35         1381 *$get_callsite_name = \&Devel::Callsite::callsite;
87             }
88             }
89              
90             1;
91              
92             __END__