File Coverage

blib/lib/Lexical/Failure/Objects.pm
Criterion Covered Total %
statement 50 173 28.9
branch 2 2 100.0
condition 1 2 50.0
subroutine 16 77 20.7
pod 5 5 100.0
total 74 259 28.5


line stmt bran cond sub pod time code
1             package Lexical::Failure::Objects;
2              
3 10     10   227 use 5.014;
  10         67  
4 10     10   61 use warnings;
  10         21  
  10         296  
5 10     10   5222 use Hash::Util::FieldHash 'fieldhash';
  10         8003  
  10         15835  
6              
7             our $VERSION = '0.000001';
8              
9             # Be invisible to Carp...
10             our @CARP_NOT = __PACKAGE__;
11              
12             # Attribute storage...
13             fieldhash my %msg_for;
14             fieldhash my %context_for;
15             fieldhash my %checked_for;
16              
17             # Constructor...
18             sub new {
19 5     5 1 30 my ($class, %option) = @_;
20 5         10 my $newobj = bless do{ \my $impl }, $class;
  5         21  
21              
22 5         66 $msg_for{$newobj} = $option{msg};
23 5         48 $context_for{$newobj} = $option{context};
24              
25 5         44 return $newobj;
26             }
27              
28             # Utilities for error generation...
29             sub _croak {
30 10     10   69 require Carp;
31 10         1272 Carp::croak(@_);
32             }
33              
34             sub _cant_use {
35 10     10   34 my ($obj, $as) = @_;
36 10   50     34 $as //= q{};
37              
38 10         20 my (undef, $file, $line, $subname) = @{$context_for{$obj}};
  10         49  
39 10         35 $checked_for{$obj} = 1;
40 10         61 _croak("$msg_for{$obj} at $file line $line\nAttempt to use failure returned by $subname" . $as);
41             }
42              
43             # How failure objects behave...
44             use overload (
45             # Fail when used as a boolean...
46 0     0   0 bool => sub { my ($self) = @_; $checked_for{$self} = 1; return; },
  0         0  
  0         0  
47 4     4   5510 q[!] => sub { my ($self) = @_; $checked_for{$self} = 1; return 1; },
  4         28  
  4         37  
48              
49             # Croak when used any other way...
50 0     0   0 q[neg] => sub { my ($self) = @_; _cant_use($self, " as negative value"); },
  0         0  
51 0     0   0 q[~] => sub { my ($self) = @_; _cant_use($self, " in bitwise complement"); },
  0         0  
52 3     3   10057 q[""] => sub { my ($self) = @_; _cant_use($self, " as string"); },
  3         15  
53 0     0   0 q[0+] => sub { my ($self) = @_; _cant_use($self, " as number"); },
  0         0  
54 0     0   0 q[qr] => sub { my ($self) = @_; _cant_use($self, " as regex"); },
  0         0  
55 0     0   0 q[++] => sub { my ($self) = @_; _cant_use($self, " in increment"); },
  0         0  
56 0     0   0 q[--] => sub { my ($self) = @_; _cant_use($self, " in decrement"); },
  0         0  
57 0     0   0 q[atan2] => sub { my ($self) = @_; _cant_use($self, " as argument to atan2"); },
  0         0  
58 0     0   0 q[cos] => sub { my ($self) = @_; _cant_use($self, " as argument to cos"); },
  0         0  
59 0     0   0 q[sin] => sub { my ($self) = @_; _cant_use($self, " as argument to sin"); },
  0         0  
60 0     0   0 q[exp] => sub { my ($self) = @_; _cant_use($self, " as argument to exp"); },
  0         0  
61 0     0   0 q[abs] => sub { my ($self) = @_; _cant_use($self, " as argument to abs"); },
  0         0  
62 0     0   0 q[log] => sub { my ($self) = @_; _cant_use($self, " as argument to log"); },
  0         0  
63 0     0   0 q[sqrt] => sub { my ($self) = @_; _cant_use($self, " as argument to sqrt"); },
  0         0  
64 0     0   0 q[int] => sub { my ($self) = @_; _cant_use($self, " as argument to int"); },
  0         0  
65 4     4   21250 q[+] => sub { my ($self) = @_; _cant_use($self, " in addition"); },
  4         28  
66 0     0   0 q[-] => sub { my ($self) = @_; _cant_use($self, " in subtraction"); },
  0         0  
67 0     0   0 q[*] => sub { my ($self) = @_; _cant_use($self, " in multiplication"); },
  0         0  
68 0     0   0 q[/] => sub { my ($self) = @_; _cant_use($self, " in division"); },
  0         0  
69 0     0   0 q[%] => sub { my ($self) = @_; _cant_use($self, " in modulo"); },
  0         0  
70 0     0   0 q[**] => sub { my ($self) = @_; _cant_use($self, " in exponentiation"); },
  0         0  
71 0     0   0 q[<<] => sub { my ($self) = @_; _cant_use($self, " in left shift"); },
  0         0  
72 0     0   0 q[>>] => sub { my ($self) = @_; _cant_use($self, " in right shift"); },
  0         0  
73 0     0   0 q[x] => sub { my ($self) = @_; _cant_use($self, " in repetition"); },
  0         0  
74 0     0   0 q[.] => sub { my ($self) = @_; _cant_use($self, " in string concatenation"); },
  0         0  
75 0     0   0 q[<>] => sub { my ($self) = @_; _cant_use($self, " in <> iterator"); },
  0         0  
76 0     0   0 q[-X] => sub { my ($self) = @_; _cant_use($self, " in filetest"); },
  0         0  
77 0     0   0 q[${}] => sub { my ($self) = @_; _cant_use($self, " as scalar reference"); },
  0         0  
78 0     0   0 q[@{}] => sub { my ($self) = @_; _cant_use($self, " as array reference"); },
  0         0  
79 3     3   9850 q[%{}] => sub { my ($self) = @_; _cant_use($self, " as hash reference"); },
  3         13  
80 0     0   0 q[&{}] => sub { my ($self) = @_; _cant_use($self, " as subroutine reference"); },
  0         0  
81 0     0   0 q[*{}] => sub { my ($self) = @_; _cant_use($self, " as typeglob reference"); },
  0         0  
82 0     0   0 q[+=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
83 0     0   0 q[-=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
84 0     0   0 q[*=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
85 0     0   0 q[/=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
86 0     0   0 q[%=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
87 0     0   0 q[**=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
88 0     0   0 q[<<=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
89 0     0   0 q[>>=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
90 0     0   0 q[x=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
91 0     0   0 q[.=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
92 0     0   0 q[&=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
93 0     0   0 q[|=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
94 0     0   0 q[^=] => sub { my ($self) = @_; _cant_use($self, " in assignment"); },
  0         0  
95 0     0   0 q[<] => sub { my ($self) = @_; _cant_use($self, " in numeric comparison"); },
  0         0  
96 0     0   0 q[<=] => sub { my ($self) = @_; _cant_use($self, " in numeric comparison"); },
  0         0  
97 0     0   0 q[>] => sub { my ($self) = @_; _cant_use($self, " in numeric comparison"); },
  0         0  
98 0     0   0 q[>=] => sub { my ($self) = @_; _cant_use($self, " in numeric comparison"); },
  0         0  
99 0     0   0 q[==] => sub { my ($self) = @_; _cant_use($self, " in numeric comparison"); },
  0         0  
100 0     0   0 q[!=] => sub { my ($self) = @_; _cant_use($self, " in numeric comparison"); },
  0         0  
101 0     0   0 q[<=>] => sub { my ($self) = @_; _cant_use($self, " in numeric comparison"); },
  0         0  
102 0     0   0 q[cmp] => sub { my ($self) = @_; _cant_use($self, " in string comparison"); },
  0         0  
103 0     0   0 q[lt] => sub { my ($self) = @_; _cant_use($self, " in string comparison"); },
  0         0  
104 0     0   0 q[le] => sub { my ($self) = @_; _cant_use($self, " in string comparison"); },
  0         0  
105 0     0   0 q[gt] => sub { my ($self) = @_; _cant_use($self, " in string comparison"); },
  0         0  
106 0     0   0 q[ge] => sub { my ($self) = @_; _cant_use($self, " in string comparison"); },
  0         0  
107 0     0   0 q[eq] => sub { my ($self) = @_; _cant_use($self, " in string comparison"); },
  0         0  
108 0     0   0 q[ne] => sub { my ($self) = @_; _cant_use($self, " in string comparison"); },
  0         0  
109 0     0   0 q[&] => sub { my ($self) = @_; _cant_use($self, " in bitwise and"); },
  0         0  
110 0     0   0 q[|] => sub { my ($self) = @_; _cant_use($self, " in bitwise or"); },
  0         0  
111 0     0   0 q[^] => sub { my ($self) = @_; _cant_use($self, " in bitwise xor"); },
  0         0  
112 0     0   0 q[~~] => sub { my ($self) = @_; _cant_use($self, " in smartmatch"); },
  0         0  
113 10     10   3323 );
  10         2693  
  10         541  
114              
115             # Throw an exception if still unchecked upon destruction...
116             sub DESTROY {
117 5     5   19532 my ($self) = @_;
118              
119 5 100       72 if (!$checked_for{$self}) {
120 1         5 $checked_for{$self} = 1;
121 1         3 say {*STDERR} "$msg_for{$self} at $context_for{$self}[1] line $context_for{$self}[2]\n";
  1         18  
122 1         132 exit();
123             }
124             }
125              
126             # Context-enquiry interface...
127 3     3 1 13 sub subname { my ($self) = @_; return $context_for{$self}[3]; }
  3         23  
128 3     3 1 10 sub line { my ($self) = @_; return $context_for{$self}[2]; }
  3         19  
129 3     3 1 8 sub file { my ($self) = @_; return $context_for{$self}[1]; }
  3         37  
130              
131             sub context {
132 3     3 1 15 my ($self) = @_;
133 3         9 my ($subname, $file, $line) = @{$context_for{$self}}[3,1,2];
  3         20  
134 3         26 return "call to $subname at $file line $line";
135             }
136              
137              
138             1; # Magic true value required at end of module
139             __END__