File Coverage

blib/lib/Gears/X.pm
Criterion Covered Total %
statement 75 81 92.5
branch 14 16 87.5
condition 6 6 100.0
subroutine 14 15 93.3
pod 5 5 100.0
total 114 123 92.6


line stmt bran cond sub pod time code
1             package Gears::X;
2             $Gears::X::VERSION = '0.101';
3 7     7   240138 use v5.40;
  7         32  
4 7     7   626 use Mooish::Base -standard;
  7         88028  
  7         73  
5              
6             use overload
7 10     10   52 q{""} => sub ($self, @) { $self->as_string },
  10         4158  
  10         21  
  10         18  
8 13     13   60 q{0+} => sub ($self, @) { $self->as_number },
  13         159  
  13         28  
  13         21  
9 7     7   428667 fallback => 1;
  7         16  
  7         111  
10              
11             our $PRINT_TRACE = $ENV{GEARS_PRINT_TRACE};
12              
13             has param 'message' => (
14             isa => Str,
15             writer => -hidden,
16             );
17              
18             has field 'trace' => (
19             isa => ArrayRef,
20             builder => 1,
21             );
22              
23             my @ignored = qw(Gears Type::Coercion);
24             my $packages_to_skip;
25             _rebuild_skip();
26              
27             sub _rebuild_skip
28             {
29 7     7   21 my $sub_re = join '|', map { quotemeta } @ignored;
  14         87  
30 7         484 $packages_to_skip = qr/^($sub_re)::/;
31             }
32              
33 0         0 sub add_ignored_namespace($self, $module)
34 0     0 1 0 {
  0         0  
  0         0  
35 0         0 push @ignored, $module;
36 0         0 _rebuild_skip;
37             }
38              
39             sub _base_class ($self)
40 13     13   26 {
  13         23  
  13         21  
41 13         27 return __PACKAGE__;
42             }
43              
44             sub _trace_config ($self)
45 14     14   26 {
  14         26  
  14         24  
46 14         73 return state $conf = {
47             max_level => 20,
48             skip_package => \$packages_to_skip,
49             skip_file => qr/\(eval \d+\)/,
50             };
51             }
52              
53             sub _build_trace ($self)
54 14     14   356772 {
  14         32  
  14         23  
55 14         27 my @trace;
56 14         61 my $trace_conf = $self->_trace_config;
57              
58 14         92 for my $call_level (0 .. $trace_conf->{max_level}) {
59 158         717 my ($package, $file, $line) = CORE::caller $call_level;
60 158 100       460 last unless defined $package;
61 144 100       724 next if $package =~ $trace_conf->{skip_package}->$*;
62 102 50       356 next if $file =~ $trace_conf->{skip_file};
63 102 100 100     489 next if @trace > 0 && $trace[-1][0] eq $file && $trace[-1][1] == $line;
      100        
64              
65 78         231 push @trace, [$file, $line];
66             }
67              
68 14         475 return \@trace;
69             }
70              
71             sub caller ($self)
72 11     11 1 20 {
  11         21  
  11         23  
73 11         91 return $self->trace->[0];
74             }
75              
76 10         22 sub raise ($self, $error = undef)
77 10     10 1 3684 {
  10         24  
  10         17  
78 10 100       37 if (defined $error) {
79 9         219 $self = $self->new(message => $error);
80             }
81              
82 10         3046 die $self;
83             }
84              
85             sub _build_message ($self)
86 12     12   21 {
  12         53  
  12         21  
87 12         55 return $self->message;
88             }
89              
90 13         28 sub as_string ($self, $trace = $PRINT_TRACE)
  13         28  
91 13     13 1 3895 {
  13         22  
92 13         46 my $raised = $self->_build_message;
93              
94 13 100       126 if ($trace) {
    50          
95 2         7 $raised .= "\nStack trace:\n";
96 2         9 foreach my $trace ($self->trace->@*) {
97 12         48 $raised .= " $trace->[0], line $trace->[1]\n";
98             }
99             }
100             elsif (defined(my $caller = $self->caller)) {
101 11         44 $raised .= " (raised at $caller->[0], line $caller->[1])";
102             }
103              
104 13         31 my $class = ref $self;
105 13         53 my $base = $self->_base_class;
106 13 100       43 if ($class eq $base) {
107 7         13 $class = '';
108             }
109             else {
110 6         203 $class =~ s/^${base}::(.+)$/[$1] /;
111             }
112              
113 13         128 return "An error occured: $class$raised";
114             }
115              
116             sub as_number ($self)
117 13     13 1 29 {
  13         25  
  13         22  
118 13         47 return refaddr $self;
119             }
120              
121             __END__