| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Throw::Back; |
|
2
|
|
|
|
|
|
|
|
|
3
|
4
|
|
|
4
|
|
193248
|
use strict; |
|
|
4
|
|
|
|
|
11
|
|
|
|
4
|
|
|
|
|
155
|
|
|
4
|
4
|
|
|
4
|
|
23
|
use warnings; |
|
|
4
|
|
|
|
|
7
|
|
|
|
4
|
|
|
|
|
1015
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
$Throw::Back::VERSION = '0.01'; |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
use overload fallback => 1, '""' => sub { |
|
9
|
0
|
|
|
0
|
|
0
|
my ($exc) = @_; |
|
10
|
0
|
|
|
|
|
0
|
my $call_stack = ''; |
|
11
|
0
|
0
|
|
|
|
0
|
if ( exists $exc->{call_stack} ) { |
|
12
|
0
|
|
|
|
|
0
|
for my $frame ( @{ $exc->{call_stack} } ) { |
|
|
0
|
|
|
|
|
0
|
|
|
13
|
0
|
|
|
|
|
0
|
my $func = $frame->[3]; |
|
14
|
0
|
|
|
|
|
0
|
$func =~ s/^$frame->[0]\:://; |
|
15
|
0
|
|
|
|
|
0
|
$call_stack .= " : $func() (file: $frame->[1], line: $frame->[2])\n"; |
|
16
|
|
|
|
|
|
|
} |
|
17
|
|
|
|
|
|
|
} |
|
18
|
|
|
|
|
|
|
|
|
19
|
0
|
0
|
|
|
|
0
|
return $exc->{string} =~ m/\n$/ ? "$exc->{string}$call_stack" : "$exc->{string} (file: $exc->{file}, line: $exc->{line})\n$call_stack"; |
|
20
|
4
|
|
|
4
|
|
25
|
}; |
|
|
4
|
|
|
|
|
17
|
|
|
|
4
|
|
|
|
|
64
|
|
|
21
|
|
|
|
|
|
|
|
|
22
|
4
|
|
|
4
|
|
6001
|
use Module::Want 0.6 (); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub throw::back { |
|
25
|
|
|
|
|
|
|
my ( $class, @args ) = @_; |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# hack for no args: |
|
28
|
|
|
|
|
|
|
if ( ref($class) eq 'Throw::Back::_arg' ) { |
|
29
|
|
|
|
|
|
|
push @args, $class; |
|
30
|
|
|
|
|
|
|
$class = undef; |
|
31
|
|
|
|
|
|
|
} |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
my $_arg = ref( $args[-1] ) eq 'Throw::Back::_arg' ? pop(@args) : bless( {}, 'Throw::Back::_arg' ); |
|
34
|
|
|
|
|
|
|
my %obj = %{$_arg}; |
|
35
|
|
|
|
|
|
|
if ( ref $class eq 'Throw::Back::_arg' ) { |
|
36
|
|
|
|
|
|
|
%obj = %{$class}; |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
my $cn = 0; |
|
40
|
|
|
|
|
|
|
my $caller; |
|
41
|
|
|
|
|
|
|
my @stack_trace; |
|
42
|
|
|
|
|
|
|
while ( my @caller = caller($cn) ) { |
|
43
|
|
|
|
|
|
|
$caller = \@caller; |
|
44
|
|
|
|
|
|
|
unshift( @{ $obj{call_stack} }, $caller ) if exists $obj{call_stack}; |
|
45
|
|
|
|
|
|
|
$cn++; |
|
46
|
|
|
|
|
|
|
} |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
$obj{file} = $caller->[1]; |
|
49
|
|
|
|
|
|
|
$obj{line} = $caller->[2]; |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
$obj{'previous_exception'} = $@ if defined $@ && ( ref($@) || length($@) ); |
|
52
|
|
|
|
|
|
|
local $@; |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
if ( defined $class ) { |
|
55
|
|
|
|
|
|
|
if ( !ref($class) && Module::Want::is_ns($class) ) { # a one word message is pointless so don’t do that! |
|
56
|
|
|
|
|
|
|
$obj{type} = $class; |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# TODO ? $class->can('throw') ? |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
if ( Module::Want::have_mod($class) && $class->can('new') ) { |
|
61
|
|
|
|
|
|
|
$obj{exception} = $class->new(@args); |
|
62
|
|
|
|
|
|
|
$obj{string} ||= eval { $obj{exception}->to_string } || "$class Exception Thrown"; |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
else { |
|
65
|
|
|
|
|
|
|
$obj{string} ||= defined $args[0] && length $args[0] ? $args[0] : "$class Exception Thrown"; |
|
66
|
|
|
|
|
|
|
} |
|
67
|
|
|
|
|
|
|
} |
|
68
|
|
|
|
|
|
|
else { |
|
69
|
|
|
|
|
|
|
if ( my $type = ref($class) ) { |
|
70
|
|
|
|
|
|
|
$obj{type} = $type; |
|
71
|
|
|
|
|
|
|
$obj{exception} = $class; |
|
72
|
|
|
|
|
|
|
$obj{string} ||= defined $args[0] && length $args[0] ? $args[0] : "$type Exception Thrown"; |
|
73
|
|
|
|
|
|
|
} |
|
74
|
|
|
|
|
|
|
else { |
|
75
|
|
|
|
|
|
|
$obj{string} ||= $class; |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
} |
|
79
|
|
|
|
|
|
|
else { |
|
80
|
|
|
|
|
|
|
$obj{string} ||= defined $args[0] && length $args[0] ? $args[0] : "Exception Thrown"; |
|
81
|
|
|
|
|
|
|
} |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
$obj{type} ||= __PACKAGE__; |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
if ( defined wantarray ) { |
|
86
|
|
|
|
|
|
|
return bless \%obj, __PACKAGE__; |
|
87
|
|
|
|
|
|
|
} |
|
88
|
|
|
|
|
|
|
else { |
|
89
|
|
|
|
|
|
|
die bless \%obj, __PACKAGE__; |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
return; |
|
92
|
|
|
|
|
|
|
} |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub throw::stack { |
|
95
|
|
|
|
|
|
|
push @_, bless( { 'call_stack' => [] }, 'Throw::Back::_arg' ); |
|
96
|
|
|
|
|
|
|
goto &throw::back; |
|
97
|
|
|
|
|
|
|
} |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub throw::text { |
|
100
|
|
|
|
|
|
|
my ( $class, $phrase, @args ) = ref( $_[0] ) || Module::Want::is_ns( $_[0] ) ? @_ : ( undef, @_ ); # a one word message is pointless so don’t do that! |
|
101
|
|
|
|
|
|
|
my $phrase_args = ref( $args[0] ) eq 'ARRAY' ? shift @args : []; |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
my $_arg = ref( $args[-1] ) eq 'Throw::Back::_arg' ? pop(@args) : bless( {}, 'Throw::Back::_arg' ); |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
if ( defined $class ) { |
|
106
|
|
|
|
|
|
|
my $lh = $class->can('locale') ? $class->locale : $class; # lazy façade baby, lazy façade! |
|
107
|
|
|
|
|
|
|
if ( $lh->can('makevar') && $lh->can('makethis_base') ) { |
|
108
|
|
|
|
|
|
|
$_arg->{string} = $lh->makevar( $phrase, @{$phrase_args} ); # parser knows throw::text() so makevar is good |
|
109
|
|
|
|
|
|
|
$_arg->{string_not_localized} = $lh->makethis_base( $phrase, @{$phrase_args} ); |
|
110
|
|
|
|
|
|
|
} |
|
111
|
|
|
|
|
|
|
elsif ( $class->can('maketext') ) { ## no extract maketext |
|
112
|
|
|
|
|
|
|
$_arg->{string} = $class->maketext( $phrase, @{$phrase_args} ); ## no extract maketext (i.e. no makevar) |
|
113
|
|
|
|
|
|
|
} |
|
114
|
|
|
|
|
|
|
} |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
if ( !exists $_arg->{string} ) { |
|
117
|
|
|
|
|
|
|
$_arg->{phrase} = $phrase; |
|
118
|
|
|
|
|
|
|
$_arg->{phrase_args} = $phrase_args; |
|
119
|
|
|
|
|
|
|
} |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
@_ = ( $class, @args, $_arg ); |
|
122
|
|
|
|
|
|
|
goto &throw::back; |
|
123
|
|
|
|
|
|
|
} |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub throw::stack::text { |
|
126
|
|
|
|
|
|
|
push @_, bless( { 'call_stack' => [] }, 'Throw::Back::_arg' ); |
|
127
|
|
|
|
|
|
|
goto &throw::text; |
|
128
|
|
|
|
|
|
|
} |
|
129
|
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# TODO ? v0.02 ?: |
|
131
|
|
|
|
|
|
|
# sub rethrow { |
|
132
|
|
|
|
|
|
|
# my ($self) = @_; |
|
133
|
|
|
|
|
|
|
# my $caller = [caller(0)]; |
|
134
|
|
|
|
|
|
|
# |
|
135
|
|
|
|
|
|
|
# $self->{file} = $caller->[1]; |
|
136
|
|
|
|
|
|
|
# $self->{line} = $caller->[2]; |
|
137
|
|
|
|
|
|
|
# $self->{call_stack} = __get_stack() if $self->{call_stack}; |
|
138
|
|
|
|
|
|
|
# |
|
139
|
|
|
|
|
|
|
# goto &__std_lazy_throw; |
|
140
|
|
|
|
|
|
|
# } |
|
141
|
|
|
|
|
|
|
# |
|
142
|
|
|
|
|
|
|
# sub PROPAGATE { # see perldoc -f die |
|
143
|
|
|
|
|
|
|
# my ($self, $file, $line) = @_; |
|
144
|
|
|
|
|
|
|
# $self->{file} = $file; |
|
145
|
|
|
|
|
|
|
# $self->{line} = $line; |
|
146
|
|
|
|
|
|
|
# return $self; |
|
147
|
|
|
|
|
|
|
# } |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
1; |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
__END__ |