File Coverage

blib/lib/DBIx/Class/Carp.pm
Criterion Covered Total %
statement 58 61 95.0
branch 29 34 85.2
condition 23 27 85.1
subroutine 11 12 91.6
pod n/a
total 121 134 90.3


line stmt bran cond sub pod time code
1             package # hide from pause
2             DBIx::Class::Carp;
3              
4 317     317   1930 use strict;
  317         803  
  317         8701  
5 317     317   1607 use warnings;
  317         561  
  317         7356  
6              
7             # load Carp early to prevent tickling of the ::Internal stash being
8             # interpreted as "Carp is already loaded" by some braindead loader
9 317     317   1836 use Carp ();
  317         619  
  317         7675  
10             $Carp::Internal{ (__PACKAGE__) }++;
11              
12 317     317   1627 use Scalar::Util ();
  317         668  
  317         244773  
13              
14             # Because... sigh
15             # There are cases out there where a user provides a can() that won't actually
16             # work as perl intends it. Since this is a reporting library, we *have* to be
17             # extra paranoid ( e.g. https://rt.cpan.org/Ticket/Display.html?id=90715 )
18             sub __safe_can ($$) {
19 29671     29671   45359 local $@;
20 29671 100       67002 local $SIG{__DIE__} if $SIG{__DIE__};
21              
22 29671         40499 my $cref;
23             eval {
24 29671         137401 $cref = $_[0]->can( $_[1] );
25              
26             # in case the can() isn't an actual UNIVERSAL::can()
27 29671 50 66     126253 die "Return value of $_[0]" . "->can(q($_[1])) is true yet not a code reference...\n"
28             if $cref and Scalar::Util::reftype($cref) ne 'CODE';
29              
30 29671         68157 1;
31 29671 50       51841 } or do {
32 0         0 undef $cref;
33              
34             # can not use DBIC::_Util::emit_loud_diag - it uses us internally
35 0 0       0 printf STDERR
36             "\n$0: !!! INTERNAL PANIC !!!\nClass '%s' implements or inherits a broken can() - PLEASE FIX ASAP!: %s\n\n",
37             ( length ref $_[0] ? ref $_[0] : $_[0] ),
38             $@,
39             ;
40             };
41              
42 29671         551735 $cref;
43             }
44              
45             sub __find_caller {
46 3069     3069   8660 my ($skip_pattern, $class) = @_;
47              
48 3069 100 100     12577 my $skip_class_data = $class->_skip_namespace_frames
49             if ($class and __safe_can($class, '_skip_namespace_frames') );
50              
51 3069 100       86984 $skip_pattern = qr/$skip_pattern|$skip_class_data/
52             if $skip_class_data;
53              
54 3069         7102 my $fr_num = 1; # skip us and the calling carp*
55              
56 3069         6416 my (@f, $origin, $eval_src);
57 3069         27654 while (@f = CORE::caller($fr_num++)) {
58              
59 33068         67118 undef $eval_src;
60              
61             next if (
62 33068 100 66     264302 $f[2] == 0
      100        
      66        
      100        
63             or
64             # there is no value reporting a sourceless eval frame
65             (
66             ( $f[3] eq '(eval)' or $f[1] =~ /^\(eval \d+\)$/ )
67             and
68             not defined ( $eval_src = (CORE::caller($fr_num))[6] )
69             )
70             or
71             $f[3] =~ /::__ANON__$/
72             );
73              
74             $origin ||= (
75             $f[3] =~ /^ (.+) :: ([^\:]+) $/x
76             and
77 26611 100 100     212831 ! $Carp::Internal{$1}
      100        
78             and
79             #############################
80             # Need a way to parameterize this for Carp::Skip
81             $1 !~ /^(?: DBIx::Class::Storage::BlockRunner | Context::Preserve | Try::Tiny | Class::Accessor::Grouped | Class::C3::Componentised | Module::Runtime | Sub::Uplevel )$/x
82             and
83             $2 !~ /^(?: throw_exception | carp | carp_unique | carp_once | dbh_do | txn_do | with_deferred_fk_checks | __delicate_rollback | dbic_internal_try )$/x
84             #############################
85             ) ? $f[3] : undef;
86              
87 26611 100 66     58738 if (
88             __safe_can( $f[0], '_skip_namespace_frames' )
89             and
90             my $extra_skip = $f[0]->_skip_namespace_frames
91             ) {
92 19365         2317883 $skip_pattern = qr/$skip_pattern|$extra_skip/;
93             }
94              
95 26611 100       385505 last if $f[0] !~ $skip_pattern;
96             }
97              
98 3069 100       20686 my $site = @f # if empty - nothing matched - full stack
    100          
99             ? ( "at $f[1] line $f[2]" . ( $eval_src ? "\n === BEGIN $f[1]\n$eval_src\n === END $f[1]" : '' ) )
100             : Carp::longmess()
101             ;
102              
103             return (
104 3069 50       31998 $site,
    100          
105             (
106             # cargo-cult from Carp::Clan
107             ! defined $origin ? ''
108             : $origin =~ /::/ ? "$origin(): "
109             : "$origin: "
110             ),
111             );
112             };
113              
114             my $warn = sub {
115             my ($ln, @warn) = @_;
116             @warn = "Warning: something's wrong" unless @warn;
117              
118             # back-compat with Carp::Clan - a warning ending with \n does
119             # not include caller info
120             warn (
121             @warn,
122             $warn[-1] =~ /\n$/ ? '' : " $ln\n"
123             );
124             };
125              
126             sub import {
127 6226     6226   20281 my (undef, $skip_pattern) = @_;
128 6226         20392 my $into = caller;
129              
130 6226 100       170423 $skip_pattern = $skip_pattern
131             ? qr/ ^ $into $ | $skip_pattern /x
132             : qr/ ^ $into $ /x
133             ;
134              
135 317     317   2481 no strict 'refs';
  317         729  
  317         99380  
136              
137 6226         41341 *{"${into}::carp"} = sub {
138 174     174   1948 $warn->(
139             __find_caller($skip_pattern, $into),
140             @_
141             );
142 6226         35368 };
143              
144 6226         16125 my $fired = {};
145 6226         33827 *{"${into}::carp_once"} = sub {
146 13 100   13   337 return if $fired->{$_[0]};
147 9         32 $fired->{$_[0]} = 1;
148              
149 9         97 $warn->(
150             __find_caller($skip_pattern, $into),
151             @_,
152             );
153 6226         24405 };
154              
155 6226         12500 my $seen;
156 6226         186240 *{"${into}::carp_unique"} = sub {
157 95     95   749 my ($ln, $calling) = __find_caller($skip_pattern, $into);
158 95         387 my $msg = join ('', $calling, @_);
159              
160             # unique carping with a hidden caller makes no sense
161 95         296 $msg =~ s/\n+$//;
162              
163 95 100       488 return if $seen->{$ln}{$msg};
164 57         203 $seen->{$ln}{$msg} = 1;
165              
166 57         221 $warn->(
167             $ln,
168             $msg,
169             );
170 6226         27194 };
171             }
172              
173             sub unimport {
174 0     0     die (__PACKAGE__ . " does not implement unimport yet\n");
175             }
176              
177             1;
178              
179             __END__