line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# -*- cperl -*- |
2
|
|
|
|
|
|
|
package Carp::Proxy; |
3
|
43
|
|
|
44
|
|
4427741
|
use warnings; |
|
43
|
|
|
|
|
88
|
|
|
43
|
|
|
|
|
1389
|
|
4
|
43
|
|
|
43
|
|
193
|
use strict; |
|
43
|
|
|
|
|
59
|
|
|
43
|
|
|
|
|
1151
|
|
5
|
43
|
|
|
43
|
|
823
|
use 5.010; |
|
43
|
|
|
|
|
109
|
|
|
43
|
|
|
|
|
1874
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.15'; |
8
|
|
|
|
|
|
|
|
9
|
43
|
|
|
43
|
|
18437
|
use Moose; |
|
43
|
|
|
|
|
12735954
|
|
|
43
|
|
|
|
|
304
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
has( 'arg', |
12
|
|
|
|
|
|
|
documentation => q(Perl's $ARG (AKA $_) at proxy invocation), |
13
|
|
|
|
|
|
|
is => 'ro', |
14
|
|
|
|
|
|
|
isa => 'Any', |
15
|
|
|
|
|
|
|
required => 1, |
16
|
|
|
|
|
|
|
); |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
has( 'as_yaml', |
19
|
|
|
|
|
|
|
documentation => q(Render message as YAML dump of Carp::Proxy object), |
20
|
|
|
|
|
|
|
is => 'rw', |
21
|
|
|
|
|
|
|
isa => 'Bool', |
22
|
|
|
|
|
|
|
lazy => 1, |
23
|
|
|
|
|
|
|
builder => '_build_as_yaml', |
24
|
|
|
|
|
|
|
); |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
has( 'banner_title', |
27
|
|
|
|
|
|
|
documentation => q(The first word(s) in the banner (at top of message)), |
28
|
|
|
|
|
|
|
is => 'rw', |
29
|
|
|
|
|
|
|
isa => 'Str', |
30
|
|
|
|
|
|
|
lazy => 1, |
31
|
|
|
|
|
|
|
builder => '_build_banner_title', |
32
|
|
|
|
|
|
|
); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
has( 'begin_hook', |
35
|
|
|
|
|
|
|
documentation => q(Callback before handler is launched), |
36
|
|
|
|
|
|
|
is => 'rw', |
37
|
|
|
|
|
|
|
isa => 'Maybe[CodeRef]', |
38
|
|
|
|
|
|
|
lazy => 1, |
39
|
|
|
|
|
|
|
builder => '_build_begin_hook', |
40
|
|
|
|
|
|
|
); |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
has( 'body_indent', |
43
|
|
|
|
|
|
|
documentation => q(paragraph indent (beyond <header_indent>)), |
44
|
|
|
|
|
|
|
is => 'rw', |
45
|
|
|
|
|
|
|
isa => 'Int', |
46
|
|
|
|
|
|
|
builder => '_build_body_indent', |
47
|
|
|
|
|
|
|
trigger => \&_validate_body_indent, |
48
|
|
|
|
|
|
|
); |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
has( 'child_error', |
51
|
|
|
|
|
|
|
documentation => q(Perl's $CHILD_ERROR (AKA $?) at proxy invocation), |
52
|
|
|
|
|
|
|
is => 'ro', |
53
|
|
|
|
|
|
|
isa => 'Any', |
54
|
|
|
|
|
|
|
required => 1, |
55
|
|
|
|
|
|
|
); |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
has( 'columns', |
58
|
|
|
|
|
|
|
documentation => q( Controls width of banner and filled() paragraphs ), |
59
|
|
|
|
|
|
|
is => 'rw', |
60
|
|
|
|
|
|
|
isa => 'Int', |
61
|
|
|
|
|
|
|
lazy => 1, |
62
|
|
|
|
|
|
|
builder => '_build_columns', |
63
|
|
|
|
|
|
|
trigger => \&_validate_columns, |
64
|
|
|
|
|
|
|
); |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
has( 'context', |
67
|
|
|
|
|
|
|
documentation => q( Stacktrace verbosity/inclusion in message ), |
68
|
|
|
|
|
|
|
is => 'rw', |
69
|
|
|
|
|
|
|
isa => 'Defined', |
70
|
|
|
|
|
|
|
lazy => 1, |
71
|
|
|
|
|
|
|
builder => '_build_context', |
72
|
|
|
|
|
|
|
trigger => \&_validate_context, |
73
|
|
|
|
|
|
|
); |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
has( 'disposition', |
76
|
|
|
|
|
|
|
documentation => q( Throwing semantics ), |
77
|
|
|
|
|
|
|
is => 'rw', |
78
|
|
|
|
|
|
|
isa => 'Defined', |
79
|
|
|
|
|
|
|
lazy => 1, |
80
|
|
|
|
|
|
|
builder => '_build_disposition', |
81
|
|
|
|
|
|
|
trigger => \&_validate_disposition, |
82
|
|
|
|
|
|
|
); |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
has( 'end_hook', |
85
|
|
|
|
|
|
|
documentation => q( Callback just before disposition ), |
86
|
|
|
|
|
|
|
is => 'rw', |
87
|
|
|
|
|
|
|
isa => 'Maybe[CodeRef]', |
88
|
|
|
|
|
|
|
lazy => 1, |
89
|
|
|
|
|
|
|
builder => '_build_end_hook', |
90
|
|
|
|
|
|
|
); |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
has( 'eval_error', |
93
|
|
|
|
|
|
|
documentation => q(Perl's $EVAL_ERROR (AKA $@) at proxy invocation), |
94
|
|
|
|
|
|
|
is => 'ro', |
95
|
|
|
|
|
|
|
isa => 'Any', |
96
|
|
|
|
|
|
|
required => 1, |
97
|
|
|
|
|
|
|
); |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
has( 'exit_code', |
100
|
|
|
|
|
|
|
documentation => q(exit-code harvested by OS when this process dies), |
101
|
|
|
|
|
|
|
is => 'rw', |
102
|
|
|
|
|
|
|
isa => 'Int', |
103
|
|
|
|
|
|
|
lazy => 1, |
104
|
|
|
|
|
|
|
builder => '_build_exit_code', |
105
|
|
|
|
|
|
|
); |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
has( 'fq_proxy_name', |
108
|
|
|
|
|
|
|
documentation => q( Fully-Qualified Proxy-Name (with pkg:: prefix)), |
109
|
|
|
|
|
|
|
is => 'rw', |
110
|
|
|
|
|
|
|
isa => 'Str', |
111
|
|
|
|
|
|
|
required => 1, |
112
|
|
|
|
|
|
|
); |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
has( 'handler_name', |
115
|
|
|
|
|
|
|
documentation => q(The name of the handler requested by the user), |
116
|
|
|
|
|
|
|
is => 'ro', |
117
|
|
|
|
|
|
|
isa => 'Str', |
118
|
|
|
|
|
|
|
required => 1, |
119
|
|
|
|
|
|
|
); |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
has( 'handler_pkgs', |
122
|
|
|
|
|
|
|
documentation => q(Search for handler subroutines in these pkgs), |
123
|
|
|
|
|
|
|
is => 'rw', |
124
|
|
|
|
|
|
|
isa => 'ArrayRef', |
125
|
|
|
|
|
|
|
lazy => 1, |
126
|
|
|
|
|
|
|
builder => '_build_handler_pkgs', |
127
|
|
|
|
|
|
|
traits => ['Array'], |
128
|
|
|
|
|
|
|
handles => |
129
|
|
|
|
|
|
|
{ |
130
|
|
|
|
|
|
|
append_handler_package => 'push', |
131
|
|
|
|
|
|
|
prepend_handler_package => 'unshift', |
132
|
|
|
|
|
|
|
list_handler_pkgs => 'elements', |
133
|
|
|
|
|
|
|
}, |
134
|
|
|
|
|
|
|
); |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
has( 'handler_prefix', |
137
|
|
|
|
|
|
|
documentation => q( Prefix applied to <handler_name> before lookup ), |
138
|
|
|
|
|
|
|
is => 'rw', |
139
|
|
|
|
|
|
|
isa => 'Maybe[Str]', |
140
|
|
|
|
|
|
|
lazy => 1, |
141
|
|
|
|
|
|
|
builder => '_build_handler_prefix', |
142
|
|
|
|
|
|
|
); |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
has( 'header_indent', |
145
|
|
|
|
|
|
|
documentation => q( Indent from left margin for paragraph headers ), |
146
|
|
|
|
|
|
|
is => 'rw', |
147
|
|
|
|
|
|
|
isa => 'Int', |
148
|
|
|
|
|
|
|
lazy => 1, |
149
|
|
|
|
|
|
|
builder => '_build_header_indent', |
150
|
|
|
|
|
|
|
trigger => \&_validate_header_indent, |
151
|
|
|
|
|
|
|
); |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
has( 'maintainer', |
154
|
|
|
|
|
|
|
documentation => q( Responsible party's email, phone ), |
155
|
|
|
|
|
|
|
is => 'rw', |
156
|
|
|
|
|
|
|
isa => 'Str', |
157
|
|
|
|
|
|
|
lazy => 1, |
158
|
|
|
|
|
|
|
builder => '_build_maintainer', |
159
|
|
|
|
|
|
|
); |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
has( 'numeric_errno', |
162
|
|
|
|
|
|
|
documentation => q(Perl's $ERRNO (AKA $!) at proxy invocation (0+$!)), |
163
|
|
|
|
|
|
|
is => 'ro', |
164
|
|
|
|
|
|
|
isa => 'Maybe[Num]', |
165
|
|
|
|
|
|
|
required => 1, |
166
|
|
|
|
|
|
|
); |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
has( 'pod_filename', |
169
|
|
|
|
|
|
|
documentation => q(The search for synopsis() POD is in this file), |
170
|
|
|
|
|
|
|
is => 'rw', |
171
|
|
|
|
|
|
|
isa => 'Str', |
172
|
|
|
|
|
|
|
lazy => 1, |
173
|
|
|
|
|
|
|
builder => '_build_pod_filename', |
174
|
|
|
|
|
|
|
); |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
has( 'proxy_filename', |
177
|
|
|
|
|
|
|
documentation => q(The filename of the function requesting the proxy ), |
178
|
|
|
|
|
|
|
is => 'ro', |
179
|
|
|
|
|
|
|
isa => 'Str', |
180
|
|
|
|
|
|
|
required => 1, |
181
|
|
|
|
|
|
|
); |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
has( 'proxy_name', |
184
|
|
|
|
|
|
|
documentation => q(The subname of the generated proxy function), |
185
|
|
|
|
|
|
|
is => 'ro', |
186
|
|
|
|
|
|
|
isa => 'Str', |
187
|
|
|
|
|
|
|
required => 1, |
188
|
|
|
|
|
|
|
); |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
has( 'proxy_package', |
191
|
|
|
|
|
|
|
documentation => q(The userland package that requested the proxy), |
192
|
|
|
|
|
|
|
is => 'ro', |
193
|
|
|
|
|
|
|
isa => 'Str', |
194
|
|
|
|
|
|
|
required => 1, |
195
|
|
|
|
|
|
|
); |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
has( 'section_title', |
198
|
|
|
|
|
|
|
documentation => q( Default title for section header ), |
199
|
|
|
|
|
|
|
is => 'rw', |
200
|
|
|
|
|
|
|
isa => 'Str', |
201
|
|
|
|
|
|
|
lazy => 1, |
202
|
|
|
|
|
|
|
builder => '_build_section_title', |
203
|
|
|
|
|
|
|
); |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
has( 'sections', |
206
|
|
|
|
|
|
|
documentation => q( List of filled/fixed/raw section requests ), |
207
|
|
|
|
|
|
|
is => 'rw', |
208
|
|
|
|
|
|
|
isa => 'ArrayRef[ArrayRef]', |
209
|
|
|
|
|
|
|
traits => ['Array'], |
210
|
|
|
|
|
|
|
handles => |
211
|
|
|
|
|
|
|
{ |
212
|
|
|
|
|
|
|
append_section => 'push', |
213
|
|
|
|
|
|
|
prepend_section => 'unshift', |
214
|
|
|
|
|
|
|
list_sections => 'elements', |
215
|
|
|
|
|
|
|
}, |
216
|
|
|
|
|
|
|
builder => '_build_sections', |
217
|
|
|
|
|
|
|
); |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
has( 'string_errno', |
220
|
|
|
|
|
|
|
documentation => q(Perl's $ERRNO (AKA $!) at proxy invocation (''.$!)), |
221
|
|
|
|
|
|
|
is => 'ro', |
222
|
|
|
|
|
|
|
isa => 'Maybe[Str]', |
223
|
|
|
|
|
|
|
required => 1, |
224
|
|
|
|
|
|
|
); |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
has( 'tags', |
227
|
|
|
|
|
|
|
documentation => q( Tag-Value store for exception-related user-data ), |
228
|
|
|
|
|
|
|
is => 'rw', |
229
|
|
|
|
|
|
|
isa => 'HashRef', |
230
|
|
|
|
|
|
|
lazy => 1, |
231
|
|
|
|
|
|
|
builder => '_build_tags', |
232
|
|
|
|
|
|
|
); |
233
|
|
|
|
|
|
|
|
234
|
43
|
|
|
43
|
|
261225
|
no Moose; |
|
43
|
|
|
|
|
89
|
|
|
43
|
|
|
|
|
229
|
|
235
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
236
|
|
|
|
|
|
|
|
237
|
43
|
|
|
43
|
|
6968
|
use Config; |
|
43
|
|
|
|
|
64
|
|
|
43
|
|
|
|
|
1719
|
|
238
|
43
|
|
|
43
|
|
193
|
use Cwd qw( abs_path ); |
|
43
|
|
|
|
|
58
|
|
|
43
|
|
|
|
|
2464
|
|
239
|
43
|
|
|
43
|
|
196
|
use English qw( -no_match_vars ); |
|
43
|
|
|
|
|
56
|
|
|
43
|
|
|
|
|
310
|
|
240
|
43
|
|
|
43
|
|
15547
|
use Sub::Name qw( subname ); |
|
43
|
|
|
|
|
74
|
|
|
43
|
|
|
|
|
2367
|
|
241
|
43
|
|
|
43
|
|
596
|
use overload '""' => \&_overload_stringification; |
|
43
|
|
|
|
|
51
|
|
|
43
|
|
|
|
|
391
|
|
242
|
43
|
|
|
43
|
|
32938
|
use Pod::Usage qw( pod2usage ); |
|
43
|
|
|
|
|
1607901
|
|
|
43
|
|
|
|
|
4443
|
|
243
|
43
|
|
|
43
|
|
25296
|
use Readonly; |
|
43
|
|
|
|
|
102229
|
|
|
43
|
|
|
|
|
2567
|
|
244
|
43
|
|
|
43
|
|
18716
|
use YAML::XS qw( Dump ); |
|
43
|
|
|
|
|
90766
|
|
|
43
|
|
|
|
|
2448
|
|
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
#----- |
247
|
|
|
|
|
|
|
# We use an internal proxy to throw our own errors. It cannot be defined |
248
|
|
|
|
|
|
|
# until later, but this lets us use bareword invocation. |
249
|
|
|
|
|
|
|
#----- |
250
|
43
|
|
|
43
|
|
22317
|
use subs qw( error ); |
|
43
|
|
|
|
|
819
|
|
|
43
|
|
|
|
|
196
|
|
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
Readonly::Scalar my $NEWLINE => ($OSNAME =~ / win /xi) ? "\r\n" : "\n"; |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
my @VALID_CONTEXT_STRINGS = qw( none die croak confess internals ); |
255
|
|
|
|
|
|
|
my $VALID_CONTEXT_REX = _fixed_string_rex( @VALID_CONTEXT_STRINGS ); |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
my @VALID_DISPOSITION_STRINGS = qw( return warn die ); |
258
|
|
|
|
|
|
|
my $VALID_DISPOSITION_REX = _fixed_string_rex( @VALID_DISPOSITION_STRINGS ); |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
#----- Some symbolic constants for indexing the list returned by caller() |
261
|
|
|
|
|
|
|
my $CALLER_PACKAGE; |
262
|
|
|
|
|
|
|
my $CALLER_FILENAME; |
263
|
|
|
|
|
|
|
my $CALLER_LINE; |
264
|
|
|
|
|
|
|
my $CALLER_SUBROUTINE; |
265
|
|
|
|
|
|
|
BEGIN { |
266
|
43
|
|
|
43
|
|
7092
|
Readonly::Scalar $CALLER_PACKAGE => 0; |
267
|
43
|
|
|
|
|
1096
|
Readonly::Scalar $CALLER_FILENAME => 1; |
268
|
43
|
|
|
|
|
572
|
Readonly::Scalar $CALLER_LINE => 2; |
269
|
43
|
|
|
|
|
531
|
Readonly::Scalar $CALLER_SUBROUTINE => 3; |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
424
|
|
|
424
|
|
34121
|
sub _overload_stringification { return $_[0]->render_message; } |
273
|
|
|
|
|
|
|
|
274
|
419
|
|
|
419
|
|
10599
|
sub _build_as_yaml { return 0; } |
275
|
375
|
|
|
375
|
|
9533
|
sub _build_banner_title { return 'Fatal'; } |
276
|
519
|
|
|
519
|
|
12602
|
sub _build_begin_hook { return undef; } |
277
|
570
|
|
|
570
|
|
16416
|
sub _build_body_indent { return 2; } |
278
|
442
|
|
|
442
|
|
11193
|
sub _build_columns { return 78; } |
279
|
378
|
|
|
378
|
|
9684
|
sub _build_context { return 'confess'; } |
280
|
422
|
|
|
422
|
|
10398
|
sub _build_disposition { return 'die'; } |
281
|
449
|
|
|
449
|
|
11095
|
sub _build_end_hook { return undef; } |
282
|
422
|
|
|
422
|
|
10275
|
sub _build_exit_code { return 1; } |
283
|
522
|
|
|
522
|
|
18734
|
sub _build_handler_pkgs { return []; } |
284
|
504
|
|
|
504
|
|
12582
|
sub _build_handler_prefix { return undef; } |
285
|
447
|
|
|
447
|
|
11549
|
sub _build_header_indent { return 2; } |
286
|
29
|
|
|
29
|
|
673
|
sub _build_maintainer { return ''; } |
287
|
28
|
|
|
28
|
|
675
|
sub _build_pod_filename { return $_[0]->proxy_filename; } |
288
|
18
|
|
|
18
|
|
64
|
sub _build_proxy_name { return 'fatal'; } |
289
|
129
|
|
|
129
|
|
2926
|
sub _build_section_title { return 'Description'; } |
290
|
541
|
|
|
541
|
|
16885
|
sub _build_sections { return []; } |
291
|
1
|
|
|
1
|
|
21
|
sub _build_tags { return {}; } |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
sub _validate_body_indent { |
294
|
7
|
|
|
7
|
|
14
|
my( $self, $indent ) = @_; |
295
|
|
|
|
|
|
|
|
296
|
7
|
100
|
|
|
|
17
|
error 'negative_body_indentation', $indent |
297
|
|
|
|
|
|
|
if $indent < 0; |
298
|
|
|
|
|
|
|
|
299
|
5
|
|
|
|
|
107
|
return; |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
sub _cp_negative_body_indentation { |
303
|
2
|
|
|
2
|
|
5
|
my( $cp, $indent ) = @_; |
304
|
|
|
|
|
|
|
|
305
|
2
|
|
|
|
|
6
|
$cp->_disallowed_setting( 'body_indent', $indent ); |
306
|
|
|
|
|
|
|
|
307
|
2
|
|
|
|
|
4
|
return; |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
sub _validate_columns { |
311
|
17
|
|
|
17
|
|
28
|
my( $self, $columns ) = @_; |
312
|
|
|
|
|
|
|
|
313
|
17
|
100
|
|
|
|
44
|
error 'insufficient_columns', $columns |
314
|
|
|
|
|
|
|
if $columns <= 0; |
315
|
|
|
|
|
|
|
|
316
|
13
|
|
|
|
|
336
|
return; |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
sub _cp_insufficient_columns { |
320
|
4
|
|
|
4
|
|
6
|
my( $cp, $columns ) = @_; |
321
|
|
|
|
|
|
|
|
322
|
4
|
|
|
|
|
12
|
$cp->_disallowed_setting( 'columns', $columns ); |
323
|
|
|
|
|
|
|
|
324
|
4
|
|
|
|
|
8
|
return; |
325
|
|
|
|
|
|
|
} |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
sub _validate_context { |
328
|
85
|
|
|
85
|
|
127
|
my( $self, $context ) = @_; |
329
|
|
|
|
|
|
|
|
330
|
85
|
100
|
100
|
|
|
785
|
error 'invalid_context_setting', $context |
331
|
|
|
|
|
|
|
if 'CODE' ne ref $context |
332
|
|
|
|
|
|
|
and $context !~ $VALID_CONTEXT_REX; |
333
|
|
|
|
|
|
|
|
334
|
77
|
|
|
|
|
1745
|
return; |
335
|
|
|
|
|
|
|
} |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
sub _cp_invalid_context_setting { |
338
|
8
|
|
|
8
|
|
10
|
my( $cp, $context ) = @_; |
339
|
|
|
|
|
|
|
|
340
|
8
|
|
|
|
|
21
|
$cp->_disallowed_setting( 'context', $context ); |
341
|
|
|
|
|
|
|
|
342
|
8
|
|
|
|
|
17
|
return; |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
sub _validate_disposition { |
346
|
44
|
|
|
44
|
|
64
|
my( $self, $disposition ) = @_; |
347
|
|
|
|
|
|
|
|
348
|
44
|
100
|
100
|
|
|
348
|
error 'invalid_disposition_setting', $disposition |
349
|
|
|
|
|
|
|
if 'CODE' ne ref $disposition |
350
|
|
|
|
|
|
|
and $disposition !~ $VALID_DISPOSITION_REX; |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
return |
353
|
38
|
|
|
|
|
1052
|
} |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
sub _cp_invalid_disposition_setting { |
356
|
6
|
|
|
6
|
|
10
|
my( $cp, $disposition ) = @_; |
357
|
|
|
|
|
|
|
|
358
|
6
|
|
|
|
|
17
|
$cp->_disallowed_setting( 'disposition', $disposition ); |
359
|
|
|
|
|
|
|
|
360
|
6
|
|
|
|
|
15
|
return; |
361
|
|
|
|
|
|
|
} |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
sub _validate_header_indent { |
364
|
7
|
|
|
7
|
|
9
|
my( $self, $indent ) = @_; |
365
|
|
|
|
|
|
|
|
366
|
7
|
100
|
|
|
|
17
|
error 'negative_header_indentation', $indent |
367
|
|
|
|
|
|
|
if $indent < 0; |
368
|
|
|
|
|
|
|
|
369
|
5
|
|
|
|
|
117
|
return; |
370
|
|
|
|
|
|
|
} |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
sub _cp_negative_header_indentation { |
373
|
2
|
|
|
2
|
|
5
|
my( $cp, $indent ) = @_; |
374
|
|
|
|
|
|
|
|
375
|
2
|
|
|
|
|
6
|
$cp->_disallowed_setting( 'header_indent', $indent ); |
376
|
|
|
|
|
|
|
|
377
|
2
|
|
|
|
|
5
|
return; |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
BEGIN { |
381
|
43
|
|
|
43
|
|
29036
|
Readonly::Scalar my $POD_USAGE_SPECIFIC_SECTION => 99; |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
sub _disallowed_setting { |
384
|
22
|
|
|
22
|
|
35
|
my( $cp, $attr, $value ) = @_; |
385
|
|
|
|
|
|
|
|
386
|
22
|
|
|
|
|
65
|
my $req = _display_code_or_string( $value ); |
387
|
|
|
|
|
|
|
|
388
|
22
|
|
|
|
|
98
|
$cp->filled(<<"EOF"); |
389
|
|
|
|
|
|
|
The requested setting of '$req' for the '$attr' attribute is not allowed. |
390
|
|
|
|
|
|
|
EOF |
391
|
|
|
|
|
|
|
|
392
|
22
|
|
|
|
|
132
|
$cp->synopsis( -verbose => $POD_USAGE_SPECIFIC_SECTION, |
393
|
|
|
|
|
|
|
-sections => ["ATTRIBUTES/$attr"], |
394
|
|
|
|
|
|
|
); |
395
|
22
|
|
|
|
|
82
|
return; |
396
|
|
|
|
|
|
|
} |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
sub _display_code_or_string { |
400
|
31
|
|
|
31
|
|
102
|
my( $value ) = @_; |
401
|
|
|
|
|
|
|
|
402
|
31
|
100
|
|
|
|
128
|
my $req |
|
|
100
|
|
|
|
|
|
403
|
|
|
|
|
|
|
= not( defined $value ) ? '(undef)' |
404
|
|
|
|
|
|
|
: ref( $value ) ? 'REF: ' . ref( $value ) |
405
|
|
|
|
|
|
|
: $value; |
406
|
|
|
|
|
|
|
|
407
|
31
|
|
|
|
|
74
|
return $req; |
408
|
|
|
|
|
|
|
} |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
sub _fixed_string_rex { |
411
|
86
|
|
|
86
|
|
3309
|
my( @strings ) = @_; |
412
|
|
|
|
|
|
|
|
413
|
86
|
|
|
|
|
1275
|
my $alternations = join ' | ', @strings; |
414
|
|
|
|
|
|
|
|
415
|
86
|
|
|
|
|
4158
|
return qr{ |
416
|
|
|
|
|
|
|
\A |
417
|
|
|
|
|
|
|
(?: $alternations ) |
418
|
|
|
|
|
|
|
\z |
419
|
|
|
|
|
|
|
}x; |
420
|
|
|
|
|
|
|
} |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
sub import { |
423
|
155
|
|
|
155
|
|
437695
|
my( $class, @proxy_attrlist_pairs ) = @_; |
424
|
|
|
|
|
|
|
|
425
|
155
|
|
|
|
|
241
|
my %by_proxyname; |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
#----- |
428
|
|
|
|
|
|
|
# If there are no args then the user is implicitly requesting a |
429
|
|
|
|
|
|
|
# proxy named 'fatal'. |
430
|
|
|
|
|
|
|
#----- |
431
|
155
|
100
|
|
|
|
900
|
if (not @proxy_attrlist_pairs) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
432
|
|
|
|
|
|
|
|
433
|
19
|
|
|
|
|
136
|
$by_proxyname{ $class->_build_proxy_name() } = {}; |
434
|
|
|
|
|
|
|
} |
435
|
|
|
|
|
|
|
#----- Just one argument names a proxy with default attributes |
436
|
|
|
|
|
|
|
elsif ( 1 == @proxy_attrlist_pairs ) { |
437
|
|
|
|
|
|
|
|
438
|
1
|
|
|
|
|
3
|
$by_proxyname{ $proxy_attrlist_pairs[0] } = {}; |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
#----- Otherwise there had better be pairs... |
441
|
|
|
|
|
|
|
elsif ( @proxy_attrlist_pairs % 2 ) { |
442
|
|
|
|
|
|
|
|
443
|
1
|
|
|
|
|
4
|
error 'unmatched_proxy_arglist', @proxy_attrlist_pairs; |
444
|
|
|
|
|
|
|
} |
445
|
|
|
|
|
|
|
else { |
446
|
|
|
|
|
|
|
|
447
|
134
|
|
|
|
|
410
|
%by_proxyname = @proxy_attrlist_pairs; |
448
|
|
|
|
|
|
|
} |
449
|
|
|
|
|
|
|
|
450
|
154
|
|
|
|
|
732
|
while(my($proxy_name, $attributes) = each %by_proxyname ) { |
451
|
|
|
|
|
|
|
|
452
|
193
|
|
|
|
|
547
|
$class->_create_proxy( $proxy_name, $attributes ); |
453
|
|
|
|
|
|
|
} |
454
|
|
|
|
|
|
|
|
455
|
154
|
|
|
|
|
3368149
|
return; |
456
|
|
|
|
|
|
|
} |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
sub _cp_unmatched_proxy_arglist { |
459
|
1
|
|
|
1
|
|
2
|
my( $cp, @mismatched_list ) = @_; |
460
|
|
|
|
|
|
|
|
461
|
1
|
|
|
|
|
1
|
my $count = @mismatched_list; |
462
|
|
|
|
|
|
|
|
463
|
1
|
|
|
|
|
1
|
my $pairings = ''; |
464
|
1
|
|
|
|
|
8
|
while( my( $proxy_name, $attr_val_hashref ) = |
465
|
|
|
|
|
|
|
splice @mismatched_list, 0, 2 |
466
|
|
|
|
|
|
|
) { |
467
|
|
|
|
|
|
|
|
468
|
2
|
100
|
|
|
|
4
|
$attr_val_hashref = '' |
469
|
|
|
|
|
|
|
if not defined $attr_val_hashref; |
470
|
|
|
|
|
|
|
|
471
|
2
|
|
|
|
|
9
|
$pairings .= "$proxy_name => $attr_val_hashref" . $NEWLINE; |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
|
474
|
1
|
|
|
|
|
5
|
$cp->filled( <<"EOF" ); |
475
|
|
|
|
|
|
|
Proxy creation arguments must come in (proxy, arglist) pairs. Each pair |
476
|
|
|
|
|
|
|
should take the form: |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
proxy name => hashref |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
An odd number of arguments were provided: |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
$pairings |
483
|
|
|
|
|
|
|
EOF |
484
|
1
|
|
|
|
|
1
|
return; |
485
|
|
|
|
|
|
|
} |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
sub _create_proxy { |
488
|
193
|
|
|
193
|
|
274
|
my( $class, $proxy_name, $requested_attributes, ) = @_; |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
#----- caller(1) should be import() called from userland |
491
|
193
|
|
|
|
|
635
|
my ( $user_pkg, $user_fname ) = (caller 1) |
492
|
|
|
|
|
|
|
[ $CALLER_PACKAGE, $CALLER_FILENAME ]; |
493
|
|
|
|
|
|
|
|
494
|
193
|
|
|
|
|
4119
|
my $fq_proxy_name = $user_pkg . '::' . $proxy_name; |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
#----- |
497
|
|
|
|
|
|
|
# The *configuration* builtin handler returns a reference to this |
498
|
|
|
|
|
|
|
# closure hash. |
499
|
|
|
|
|
|
|
#----- |
500
|
193
|
|
|
|
|
884
|
my %attrs = ( proxy_filename => $user_fname, |
501
|
|
|
|
|
|
|
proxy_name => $proxy_name, |
502
|
|
|
|
|
|
|
proxy_package => $user_pkg, |
503
|
|
|
|
|
|
|
fq_proxy_name => $fq_proxy_name, |
504
|
193
|
|
|
|
|
342
|
%{ $requested_attributes }, |
505
|
|
|
|
|
|
|
); |
506
|
|
|
|
|
|
|
|
507
|
193
|
|
|
|
|
537
|
my $proxy_coderef = _define_proxy( $class, \%attrs ); |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
#----- |
510
|
|
|
|
|
|
|
# Name the coderef so that caller() reports the name instead of ANON. |
511
|
|
|
|
|
|
|
#----- |
512
|
193
|
|
|
|
|
1057
|
subname( $fq_proxy_name, $proxy_coderef ); |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
#----- Install the proxy in userland |
515
|
|
|
|
|
|
|
{ |
516
|
43
|
|
|
43
|
|
16936
|
no strict 'refs'; |
|
43
|
|
|
|
|
104
|
|
|
43
|
|
|
|
|
81589
|
|
|
193
|
|
|
|
|
214
|
|
517
|
193
|
|
|
|
|
229
|
*{ $fq_proxy_name } = $proxy_coderef; |
|
193
|
|
|
|
|
831
|
|
518
|
|
|
|
|
|
|
} |
519
|
|
|
|
|
|
|
|
520
|
193
|
|
|
|
|
771
|
return; |
521
|
|
|
|
|
|
|
} |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
sub _define_proxy { |
524
|
193
|
|
|
193
|
|
258
|
my( $class, $attrs ) = @_; |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
return sub { |
527
|
594
|
|
|
594
|
|
4256858
|
my( $handler_name, @optional_arguments ) = @_; |
|
|
|
|
594
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
|
139
|
|
|
|
528
|
|
|
|
|
|
|
|
529
|
594
|
100
|
|
|
|
1742
|
return $attrs |
530
|
|
|
|
|
|
|
if $handler_name eq '*configuration*'; |
531
|
|
|
|
|
|
|
|
532
|
584
|
|
|
|
|
23764
|
my $cp = $class->new({ |
533
|
|
|
|
|
|
|
arg => $ARG, # $_ |
534
|
|
|
|
|
|
|
child_error => $CHILD_ERROR, # $? |
535
|
|
|
|
|
|
|
eval_error => $EVAL_ERROR, # $@ |
536
|
|
|
|
|
|
|
numeric_errno => 0 + $ERRNO, # $! |
537
|
|
|
|
|
|
|
string_errno => '' . $ERRNO, # $! |
538
|
|
|
|
|
|
|
handler_name => $handler_name, |
539
|
584
|
|
|
|
|
2787
|
%{ $attrs }, |
540
|
|
|
|
|
|
|
}); |
541
|
|
|
|
|
|
|
|
542
|
526
|
|
|
|
|
17123
|
$cp->append_handler_package( $cp->proxy_package ); |
543
|
|
|
|
|
|
|
|
544
|
526
|
|
|
|
|
13827
|
my $begin_hook = $cp->begin_hook; |
545
|
526
|
100
|
|
|
|
1150
|
$begin_hook->( $cp ) |
546
|
|
|
|
|
|
|
if defined $begin_hook; |
547
|
|
|
|
|
|
|
|
548
|
526
|
|
|
|
|
1558
|
$cp->call( $handler_name, @optional_arguments ); |
549
|
|
|
|
|
|
|
|
550
|
460
|
|
|
|
|
1233
|
$cp->add_context; |
551
|
|
|
|
|
|
|
|
552
|
455
|
|
|
|
|
12197
|
my $end_hook = $cp->end_hook; |
553
|
455
|
100
|
|
|
|
1039
|
$end_hook->( $cp ) |
554
|
|
|
|
|
|
|
if defined $end_hook; |
555
|
|
|
|
|
|
|
|
556
|
455
|
|
|
|
|
1220
|
return $cp->perform_disposition; |
557
|
193
|
|
|
|
|
931
|
}; |
558
|
|
|
|
|
|
|
} |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
sub perform_disposition { |
561
|
455
|
|
|
455
|
1
|
568
|
my( $self ) = @_; |
562
|
|
|
|
|
|
|
|
563
|
455
|
|
|
|
|
11904
|
my $disposition = $self->disposition; |
564
|
|
|
|
|
|
|
|
565
|
455
|
100
|
|
|
|
2116
|
if ( not defined $disposition ) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
566
|
|
|
|
|
|
|
|
567
|
1
|
|
|
|
|
16
|
error 'unknown_disposition', $self; |
568
|
|
|
|
|
|
|
} |
569
|
|
|
|
|
|
|
elsif ( 'CODE' eq ref $disposition ) { |
570
|
|
|
|
|
|
|
|
571
|
8
|
|
|
|
|
27
|
return $disposition->( $self ); |
572
|
|
|
|
|
|
|
} |
573
|
|
|
|
|
|
|
elsif ( 'warn' eq $disposition ) { |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
## no critic( ErrorHandling::RequireCarping ) |
576
|
2
|
|
|
|
|
15
|
warn $self; |
577
|
2
|
|
|
|
|
22
|
return (); |
578
|
|
|
|
|
|
|
} |
579
|
|
|
|
|
|
|
elsif ( 'die' eq $disposition ) { |
580
|
|
|
|
|
|
|
|
581
|
423
|
|
|
|
|
11018
|
local $ERRNO = $self->exit_code; |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
## no critic( ErrorHandling::RequireCarping ) |
584
|
423
|
|
|
|
|
4782
|
die $self; |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
elsif ( 'return' ne $disposition ) { |
587
|
|
|
|
|
|
|
|
588
|
1
|
|
|
|
|
5
|
error 'unknown_disposition', $self; |
589
|
|
|
|
|
|
|
} |
590
|
|
|
|
|
|
|
|
591
|
20
|
|
|
|
|
285
|
return $self; |
592
|
|
|
|
|
|
|
} |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
sub _cp_unknown_disposition { |
595
|
2
|
|
|
2
|
|
5
|
my( $cp, $original_cp ) = @_; |
596
|
|
|
|
|
|
|
|
597
|
2
|
|
|
|
|
88
|
my $disp = _display_code_or_string( $original_cp->disposition ); |
598
|
|
|
|
|
|
|
|
599
|
2
|
|
|
|
|
9
|
my $possibilities = join ' ', @VALID_DISPOSITION_STRINGS; |
600
|
|
|
|
|
|
|
|
601
|
2
|
|
|
|
|
7
|
_unsupported_attribute_value( $cp, |
602
|
|
|
|
|
|
|
$original_cp, |
603
|
|
|
|
|
|
|
'disposition', |
604
|
|
|
|
|
|
|
$disp, |
605
|
|
|
|
|
|
|
$possibilities ); |
606
|
|
|
|
|
|
|
|
607
|
2
|
|
|
|
|
3
|
return; |
608
|
|
|
|
|
|
|
} |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
sub _unsupported_attribute_value { |
611
|
6
|
|
|
6
|
|
11
|
my( $cp, $original_cp, $attr, $val, $possibilities ) = @_; |
612
|
|
|
|
|
|
|
|
613
|
6
|
|
|
|
|
40
|
$cp->filled(<<"EOF"); |
614
|
|
|
|
|
|
|
The program has encountered an error. The developers attempted to |
615
|
|
|
|
|
|
|
diagnose the error but they made a mistake during the diagnosis. |
616
|
|
|
|
|
|
|
There are now two errors. You should complain! |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
The secondary error is an attempt to use an unsupported value for |
619
|
|
|
|
|
|
|
an attribute. |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
$attr: '$val' |
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
The supported values for $attr, beyond a CodeRef, are: |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
$possibilities |
626
|
|
|
|
|
|
|
EOF |
627
|
|
|
|
|
|
|
|
628
|
6
|
|
|
|
|
20
|
$cp->_describe_primary_error( $original_cp ); |
629
|
6
|
|
|
|
|
8
|
return; |
630
|
|
|
|
|
|
|
} |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
sub _describe_primary_error { |
633
|
14
|
|
|
14
|
|
20
|
my( $self, $original_cp ) = @_; |
634
|
|
|
|
|
|
|
|
635
|
14
|
|
|
|
|
36
|
$self->contact_maintainer(); |
636
|
|
|
|
|
|
|
|
637
|
14
|
|
|
|
|
38
|
$self->filled(<<'EOF', 'Primary Error' ); |
638
|
|
|
|
|
|
|
The remaining sections attempt to describe the original error. |
639
|
|
|
|
|
|
|
EOF |
640
|
|
|
|
|
|
|
|
641
|
14
|
|
|
|
|
355
|
my $st = $original_cp->section_title; |
642
|
14
|
|
|
|
|
464
|
foreach my $section ( $original_cp->list_sections ) { |
643
|
|
|
|
|
|
|
|
644
|
8
|
100
|
|
|
|
33
|
my $primary_title = defined( $section->[2] ) |
645
|
|
|
|
|
|
|
? $section->[2] |
646
|
|
|
|
|
|
|
: $st; |
647
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
#----- Turn 'Description' into 'Primary Description' etc. |
649
|
8
|
|
|
|
|
32
|
$primary_title =~ s/ ^ /Primary /x; |
650
|
|
|
|
|
|
|
|
651
|
8
|
|
|
|
|
361
|
$self->append_section([ $section->[0], |
652
|
|
|
|
|
|
|
$section->[1], |
653
|
|
|
|
|
|
|
$primary_title ]); |
654
|
|
|
|
|
|
|
} |
655
|
|
|
|
|
|
|
|
656
|
14
|
|
|
|
|
22
|
return; |
657
|
|
|
|
|
|
|
} |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
sub add_context { |
660
|
460
|
|
|
460
|
1
|
579
|
my( $self ) = @_; |
661
|
|
|
|
|
|
|
|
662
|
460
|
|
|
|
|
13080
|
my $context = $self->context; |
663
|
|
|
|
|
|
|
|
664
|
460
|
100
|
|
|
|
2650
|
if ( not defined $context ) { error 'unknown_context', $self; } |
|
2
|
100
|
|
|
|
4
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
665
|
4
|
|
|
|
|
10
|
elsif ( 'CODE' eq ref $context ) { $context->($self); } |
666
|
4
|
|
|
|
|
12
|
elsif ( 'die' eq $context ) { $self->_die_context(); } |
667
|
6
|
|
|
|
|
22
|
elsif ( 'croak' eq $context ) { $self->_croak_context(); } |
668
|
387
|
|
|
|
|
954
|
elsif ( 'confess' eq $context ) { $self->_confess_context(); } |
669
|
46
|
|
|
|
|
166
|
elsif ( 'internals' eq $context ) { $self->_internals_context(); } |
670
|
2
|
|
|
|
|
8
|
elsif ( 'none' ne $context ) { error 'unknown_context', $self; } |
671
|
|
|
|
|
|
|
|
672
|
455
|
|
|
|
|
660
|
return; |
673
|
|
|
|
|
|
|
} |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
sub _die_context { |
676
|
4
|
|
|
4
|
|
6
|
my( $self ) = @_; |
677
|
|
|
|
|
|
|
|
678
|
4
|
|
|
|
|
10
|
my $caller_index = $self->_find_proxy_frame(); |
679
|
|
|
|
|
|
|
|
680
|
4
|
|
|
|
|
16
|
my( $file, $line, $subr ) = $self->_file_line_subr( $caller_index ); |
681
|
|
|
|
|
|
|
|
682
|
4
|
|
|
|
|
12
|
$self->_single_frame_context( $file, $line, $subr ); |
683
|
|
|
|
|
|
|
|
684
|
4
|
|
|
|
|
6
|
return; |
685
|
|
|
|
|
|
|
} |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
sub _croak_context { |
688
|
6
|
|
|
6
|
|
10
|
my( $self ) = @_; |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
#----- |
691
|
|
|
|
|
|
|
# 'croak' semantics asks us to go back one additional frame from |
692
|
|
|
|
|
|
|
# where the proxy was called. |
693
|
|
|
|
|
|
|
#----- |
694
|
6
|
|
|
|
|
31
|
my $caller_index = 1 + $self->_find_proxy_frame(); |
695
|
|
|
|
|
|
|
|
696
|
6
|
|
|
|
|
24
|
my( $file, $line, $subr ) = $self->_file_line_subr( $caller_index ); |
697
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
#----- |
699
|
|
|
|
|
|
|
# If the proxy was invoked from top-level code then there is no |
700
|
|
|
|
|
|
|
# caller to report. In this case we fallback to 'die' semantics. |
701
|
|
|
|
|
|
|
#----- |
702
|
6
|
100
|
|
|
|
26
|
if (not defined $file) { |
703
|
|
|
|
|
|
|
|
704
|
1
|
|
|
|
|
28
|
--$caller_index; |
705
|
|
|
|
|
|
|
|
706
|
1
|
|
|
|
|
23
|
( $file, $line, $subr ) = $self->_file_line_subr( $caller_index ); |
707
|
|
|
|
|
|
|
} |
708
|
|
|
|
|
|
|
|
709
|
6
|
|
|
|
|
23
|
$self->_single_frame_context( $file, $line, $subr ); |
710
|
6
|
|
|
|
|
10
|
return; |
711
|
|
|
|
|
|
|
} |
712
|
|
|
|
|
|
|
|
713
|
|
|
|
|
|
|
sub _confess_context { |
714
|
387
|
|
|
387
|
|
467
|
my( $self ) = @_; |
715
|
|
|
|
|
|
|
|
716
|
387
|
|
|
|
|
934
|
my $caller_index = $self->_find_proxy_frame(); |
717
|
|
|
|
|
|
|
|
718
|
386
|
|
|
|
|
1112
|
$self->_multi_frame_context( $caller_index ); |
719
|
386
|
|
|
|
|
520
|
return; |
720
|
|
|
|
|
|
|
} |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
sub _internals_context { |
723
|
46
|
|
|
46
|
|
70
|
my( $self ) = @_; |
724
|
|
|
|
|
|
|
|
725
|
46
|
|
|
|
|
131
|
$self->_multi_frame_context( undef ); |
726
|
46
|
|
|
|
|
58
|
return; |
727
|
|
|
|
|
|
|
} |
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
sub _cp_unknown_context { |
730
|
4
|
|
|
4
|
|
6
|
my( $cp, $original_cp ) = @_; |
731
|
|
|
|
|
|
|
|
732
|
4
|
|
|
|
|
86
|
my $context = _display_code_or_string( $original_cp->context ); |
733
|
|
|
|
|
|
|
|
734
|
4
|
|
|
|
|
12
|
my $possibilities = join ' ', @VALID_CONTEXT_STRINGS; |
735
|
|
|
|
|
|
|
|
736
|
4
|
|
|
|
|
10
|
_unsupported_attribute_value( $cp, |
737
|
|
|
|
|
|
|
$original_cp, |
738
|
|
|
|
|
|
|
'context', |
739
|
|
|
|
|
|
|
$context, |
740
|
|
|
|
|
|
|
$possibilities ); |
741
|
|
|
|
|
|
|
|
742
|
4
|
|
|
|
|
6
|
return; |
743
|
|
|
|
|
|
|
} |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
sub _find_proxy_frame { |
746
|
402
|
|
|
402
|
|
469
|
my( $self ) = @_; |
747
|
|
|
|
|
|
|
|
748
|
402
|
|
|
|
|
11145
|
my $fqp = $self->fq_proxy_name; |
749
|
|
|
|
|
|
|
|
750
|
402
|
|
|
|
|
566
|
my $frame = 1; |
751
|
402
|
|
|
|
|
350
|
while (1) { |
752
|
|
|
|
|
|
|
|
753
|
1214
|
|
|
|
|
2747
|
my( $sub ) = (caller $frame)[ $CALLER_SUBROUTINE ]; |
754
|
|
|
|
|
|
|
|
755
|
1214
|
100
|
|
|
|
48423
|
error 'no_proxy_frame', $self |
756
|
|
|
|
|
|
|
if not defined $sub; |
757
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
last |
759
|
1213
|
100
|
|
|
|
2266
|
if $sub eq $fqp; |
760
|
|
|
|
|
|
|
|
761
|
812
|
|
|
|
|
836
|
++$frame; |
762
|
|
|
|
|
|
|
} |
763
|
|
|
|
|
|
|
|
764
|
401
|
|
|
|
|
704
|
return $frame |
765
|
|
|
|
|
|
|
} |
766
|
|
|
|
|
|
|
|
767
|
|
|
|
|
|
|
sub _cp_no_proxy_frame { |
768
|
1
|
|
|
1
|
|
3
|
my( $cp, $original_cp ) = @_; |
769
|
|
|
|
|
|
|
|
770
|
1
|
|
|
|
|
3
|
my $frames = ''; |
771
|
1
|
|
|
|
|
4
|
for( my $i=0; 1; ++$i ) { |
772
|
|
|
|
|
|
|
|
773
|
10
|
|
|
|
|
26
|
my( $subr ) = (caller $i)[ $CALLER_SUBROUTINE ]; |
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
last |
776
|
10
|
100
|
|
|
|
772
|
if not defined $subr; |
777
|
|
|
|
|
|
|
|
778
|
9
|
|
|
|
|
33
|
$frames .= " $i => $subr" . $NEWLINE; |
779
|
|
|
|
|
|
|
} |
780
|
|
|
|
|
|
|
|
781
|
1
|
|
|
|
|
36
|
my $proxy = $original_cp->fq_proxy_name; |
782
|
|
|
|
|
|
|
|
783
|
1
|
|
|
|
|
15
|
$cp->filled(<<"EOF"); |
784
|
|
|
|
|
|
|
The callstack does not appear to contain a frame for the proxy. This is |
785
|
|
|
|
|
|
|
an internal error. The proxy name that was the target of the search is: |
786
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
$proxy |
788
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
The following list contains the stackframe index and the associated subrotine |
790
|
|
|
|
|
|
|
name: |
791
|
|
|
|
|
|
|
EOF |
792
|
|
|
|
|
|
|
|
793
|
1
|
|
|
|
|
3
|
$cp->fixed( $frames, '' ); |
794
|
|
|
|
|
|
|
|
795
|
1
|
|
|
|
|
5
|
$cp->_describe_primary_error( $original_cp ); |
796
|
1
|
|
|
|
|
1
|
return; |
797
|
|
|
|
|
|
|
} |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
sub _file_line_subr { |
800
|
2133
|
|
|
2133
|
|
2275
|
my( $self, $caller_index ) = @_; |
801
|
|
|
|
|
|
|
|
802
|
2133
|
|
|
|
|
1660
|
my( $file, $line, $subr ); |
803
|
|
|
|
|
|
|
|
804
|
2133
|
|
|
|
|
2141
|
eval{ |
805
|
2133
|
|
|
|
|
5182
|
( $file, $line, $subr ) = |
806
|
|
|
|
|
|
|
(caller 1 + $caller_index)[ |
807
|
|
|
|
|
|
|
$CALLER_FILENAME, |
808
|
|
|
|
|
|
|
$CALLER_LINE, |
809
|
|
|
|
|
|
|
$CALLER_SUBROUTINE, |
810
|
|
|
|
|
|
|
]; |
811
|
|
|
|
|
|
|
}; |
812
|
|
|
|
|
|
|
|
813
|
2133
|
50
|
|
|
|
150985
|
return $EVAL_ERROR ? () : ($file, $line, $subr); |
814
|
|
|
|
|
|
|
} |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
sub _single_frame_context { |
817
|
10
|
|
|
10
|
|
14
|
my( $self, $file, $line, $subr ) = @_; |
818
|
|
|
|
|
|
|
|
819
|
10
|
|
|
|
|
33
|
my $whence = $self->_make_frame_report( $file, $line, $subr ); |
820
|
|
|
|
|
|
|
|
821
|
10
|
|
|
|
|
44
|
$self->fixed( $whence, 'Exception' ); |
822
|
|
|
|
|
|
|
|
823
|
10
|
|
|
|
|
14
|
return; |
824
|
|
|
|
|
|
|
} |
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
sub _section_indent { |
827
|
2573
|
|
|
2573
|
|
2924
|
my( $self ) = @_; |
828
|
|
|
|
|
|
|
|
829
|
2573
|
|
|
|
|
62277
|
return $self->body_indent + $self->header_indent; |
830
|
|
|
|
|
|
|
} |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
sub _make_frame_report { |
833
|
1700
|
|
|
1700
|
|
2377
|
my( $self, $file, $line, $subr ) = @_; |
834
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
#----- We want to report just the basename of the subroutine (no pkg) |
836
|
1700
|
|
|
|
|
7154
|
$subr =~ s/\A .+ :: //x; |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
#----- |
839
|
|
|
|
|
|
|
# If the filename is short enough then it will appear on the same line |
840
|
|
|
|
|
|
|
# as the subr and the line number. If the filename is too long then |
841
|
|
|
|
|
|
|
# we put the filename on the next line and indent by an extra amount. |
842
|
|
|
|
|
|
|
# The extra amount is an additional body_indent, or 2 spaces if there |
843
|
|
|
|
|
|
|
# is no body indent. |
844
|
|
|
|
|
|
|
#----- |
845
|
1700
|
|
100
|
|
|
47794
|
my $file_indent = $self->body_indent || 2; |
846
|
|
|
|
|
|
|
|
847
|
1700
|
|
|
|
|
2951
|
my $section_indent = $self->_section_indent; |
848
|
|
|
|
|
|
|
|
849
|
1700
|
|
|
|
|
3403
|
my $whence = "$subr called from line $line of"; |
850
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
#----- |
852
|
|
|
|
|
|
|
# If we were to add the filename to whence then it would need to be |
853
|
|
|
|
|
|
|
# separated by a space (+ 1). Also we need to account for the fact |
854
|
|
|
|
|
|
|
# that the report will form the body of a fixed() section, so there |
855
|
|
|
|
|
|
|
# will be a section indent in front of whence. |
856
|
|
|
|
|
|
|
#----- |
857
|
1700
|
|
|
|
|
2716
|
my $length_with_file = |
858
|
|
|
|
|
|
|
$section_indent + length( $whence ) + 1 + length( $file ); |
859
|
|
|
|
|
|
|
|
860
|
1700
|
100
|
|
|
|
41618
|
$whence .= ($self->columns >= $length_with_file ) |
861
|
|
|
|
|
|
|
? ' ' |
862
|
|
|
|
|
|
|
: $NEWLINE . (' ' x $file_indent); |
863
|
|
|
|
|
|
|
|
864
|
1700
|
|
|
|
|
2688
|
$whence .= $file . $NEWLINE; |
865
|
|
|
|
|
|
|
|
866
|
1700
|
|
|
|
|
4337
|
return $whence; |
867
|
|
|
|
|
|
|
} |
868
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
sub _multi_frame_context { |
870
|
432
|
|
|
432
|
|
596
|
my( $self, $starting_frame ) = @_; |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
#----- |
873
|
|
|
|
|
|
|
# We have to add an extra frame to account for ourselves, unless |
874
|
|
|
|
|
|
|
# they want 'internals', in which case they want everything. |
875
|
|
|
|
|
|
|
#----- |
876
|
432
|
100
|
|
|
|
1157
|
$starting_frame = defined( $starting_frame ) |
877
|
|
|
|
|
|
|
? 1 + $starting_frame |
878
|
|
|
|
|
|
|
: 0; |
879
|
|
|
|
|
|
|
|
880
|
432
|
|
|
|
|
598
|
my $stacktrace = ''; |
881
|
432
|
|
|
|
|
589
|
for( my $frame = $starting_frame; 1; ++$frame ) { |
882
|
|
|
|
|
|
|
|
883
|
2122
|
|
|
|
|
4061
|
my( $file, $line, $subr ) = $self->_file_line_subr( $frame ); |
884
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
last |
886
|
2122
|
100
|
|
|
|
4358
|
if not defined $file; |
887
|
|
|
|
|
|
|
|
888
|
1690
|
|
|
|
|
3145
|
$stacktrace .= $self->_make_frame_report( $file, $line, $subr ); |
889
|
|
|
|
|
|
|
} |
890
|
|
|
|
|
|
|
|
891
|
432
|
|
|
|
|
1209
|
$self->fixed( $stacktrace, 'Stacktrace' ); |
892
|
|
|
|
|
|
|
|
893
|
432
|
|
|
|
|
521
|
return; |
894
|
|
|
|
|
|
|
} |
895
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
sub filled { |
898
|
416
|
|
|
416
|
1
|
941
|
my( $self, $content, $title ) = @_; |
899
|
|
|
|
|
|
|
|
900
|
416
|
|
|
|
|
16326
|
$self->append_section([ 'filled_section', $content, $title ]); |
901
|
416
|
|
|
|
|
588
|
return; |
902
|
|
|
|
|
|
|
} |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
sub fixed { |
905
|
501
|
|
|
501
|
1
|
846
|
my( $self, $content, $title ) = @_; |
906
|
|
|
|
|
|
|
|
907
|
501
|
|
|
|
|
20086
|
$self->append_section([ 'fixed_section', $content, $title ]); |
908
|
501
|
|
|
|
|
664
|
return; |
909
|
|
|
|
|
|
|
} |
910
|
|
|
|
|
|
|
|
911
|
|
|
|
|
|
|
sub raw { |
912
|
1
|
|
|
1
|
1
|
8
|
my( $self, $content ) = @_; |
913
|
|
|
|
|
|
|
|
914
|
1
|
|
|
|
|
33
|
$self->append_section([ 'raw_section', $content ]); |
915
|
1
|
|
|
|
|
2
|
return; |
916
|
|
|
|
|
|
|
} |
917
|
|
|
|
|
|
|
|
918
|
|
|
|
|
|
|
sub filled_section { |
919
|
406
|
|
|
406
|
1
|
559
|
my( $self, $content, $title ) = @_; |
920
|
|
|
|
|
|
|
|
921
|
406
|
100
|
|
|
|
1408
|
return '' |
922
|
|
|
|
|
|
|
if $content =~ /\A \s* \z/x; |
923
|
|
|
|
|
|
|
|
924
|
405
|
|
|
|
|
951
|
my $buffer = $self->header( $title ); |
925
|
405
|
|
|
|
|
10452
|
my $columns = $self->columns; |
926
|
|
|
|
|
|
|
|
927
|
405
|
|
|
|
|
1958
|
my @paragraphs = split / (?: \r? \n){2,} /x, $content; |
928
|
|
|
|
|
|
|
|
929
|
405
|
|
|
|
|
885
|
my $section_indent = ' ' x $self->_section_indent; |
930
|
|
|
|
|
|
|
|
931
|
405
|
|
|
|
|
769
|
foreach my $p (@paragraphs) { |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
#----- You need words to make a paragraph |
934
|
|
|
|
|
|
|
next |
935
|
443
|
100
|
|
|
|
1370
|
if $p =~ /\A \s* \z/x; |
936
|
|
|
|
|
|
|
|
937
|
442
|
|
|
|
|
911
|
$buffer .= _fill_paragraph( $section_indent, $columns, $p ); |
938
|
|
|
|
|
|
|
} |
939
|
|
|
|
|
|
|
|
940
|
405
|
|
|
|
|
1376
|
return $buffer; |
941
|
|
|
|
|
|
|
} |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
sub _fill_paragraph { |
944
|
442
|
|
|
442
|
|
600
|
my( $indent, $columns, $text ) = @_; |
945
|
|
|
|
|
|
|
|
946
|
|
|
|
|
|
|
#----- Whitespace, where carriage-returns and newlines don't count. |
947
|
442
|
|
|
|
|
1530
|
my( $leading_ws ) = $text =~ /\A ( [^\r\n\S]* ) /x; |
948
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
#----- Any non-tab whitespace (vertical tabs, formfeeds etc) become spaces |
950
|
442
|
|
|
|
|
806
|
$leading_ws =~ tr/\t/ /c; |
951
|
442
|
|
|
|
|
955
|
$leading_ws = $indent . _expand_tabs( $leading_ws ); |
952
|
|
|
|
|
|
|
|
953
|
442
|
|
|
|
|
2429
|
my @words = split ' ', $text; |
954
|
442
|
|
|
|
|
941
|
my $line = $leading_ws . shift @words; |
955
|
442
|
|
|
|
|
548
|
my $buffer = ''; |
956
|
|
|
|
|
|
|
|
957
|
442
|
|
|
|
|
691
|
foreach my $w (@words) { |
958
|
|
|
|
|
|
|
|
959
|
4000
|
100
|
|
|
|
5199
|
if (( length( $line ) + 1 + length( $w )) <= $columns) { |
960
|
|
|
|
|
|
|
|
961
|
3855
|
|
|
|
|
4240
|
$line .= ' ' . $w; |
962
|
|
|
|
|
|
|
} |
963
|
|
|
|
|
|
|
else { |
964
|
|
|
|
|
|
|
|
965
|
145
|
|
|
|
|
260
|
$buffer .= $line . $NEWLINE; |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
#----- Always eat one word, even if it exceeds columns |
968
|
145
|
|
|
|
|
254
|
$line = $leading_ws . $w; |
969
|
|
|
|
|
|
|
} |
970
|
|
|
|
|
|
|
} |
971
|
|
|
|
|
|
|
|
972
|
442
|
|
|
|
|
1030
|
$buffer .= $line . $NEWLINE . $NEWLINE; |
973
|
442
|
|
|
|
|
1411
|
return $buffer; |
974
|
|
|
|
|
|
|
} |
975
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
BEGIN{ |
977
|
43
|
|
|
43
|
|
224
|
Readonly::Scalar my $TAB => 8; |
978
|
|
|
|
|
|
|
|
979
|
|
|
|
|
|
|
sub _expand_tabs { |
980
|
2735
|
|
|
2735
|
|
2382
|
my( $text ) = @_; |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
#----- Keep replacing the first tab as long as there are tabs |
983
|
2735
|
|
|
|
|
4840
|
1 while $text =~ s{ \A ( [^\t]* ) \t } |
984
|
10
|
|
|
|
|
49
|
{ $1 . (' ' x ($TAB - (length($1) % $TAB))) }xe; |
985
|
|
|
|
|
|
|
|
986
|
2735
|
|
|
|
|
5032
|
return $text; |
987
|
|
|
|
|
|
|
} |
988
|
|
|
|
|
|
|
} |
989
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
sub fixed_section { |
991
|
468
|
|
|
468
|
1
|
654
|
my( $self, $content, $title ) = @_; |
992
|
|
|
|
|
|
|
|
993
|
468
|
|
|
|
|
891
|
my $buffer = $self->header( $title ); |
994
|
468
|
|
|
|
|
1059
|
my $indent = ' ' x $self->_section_indent; |
995
|
|
|
|
|
|
|
|
996
|
468
|
|
|
|
|
3870
|
my @lines = split / \r? \n /x, $content; |
997
|
468
|
|
|
|
|
862
|
foreach my $l (@lines) { |
998
|
|
|
|
|
|
|
|
999
|
2293
|
|
|
|
|
2764
|
$buffer |
1000
|
|
|
|
|
|
|
.= $indent |
1001
|
|
|
|
|
|
|
. _expand_tabs( $l ) |
1002
|
|
|
|
|
|
|
. $NEWLINE; |
1003
|
|
|
|
|
|
|
} |
1004
|
|
|
|
|
|
|
|
1005
|
468
|
|
|
|
|
4023
|
$buffer =~ s/ \s+ \z//x; |
1006
|
468
|
|
|
|
|
937
|
$buffer .= $NEWLINE . $NEWLINE; |
1007
|
|
|
|
|
|
|
|
1008
|
468
|
|
|
|
|
1915
|
return $buffer; |
1009
|
|
|
|
|
|
|
} |
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
sub raw_section { |
1012
|
1
|
|
|
1
|
1
|
4
|
my( $self, $content ) = @_; |
1013
|
|
|
|
|
|
|
|
1014
|
1
|
|
|
|
|
3
|
return $content; |
1015
|
|
|
|
|
|
|
} |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
sub _cp_missing_identifier { |
1018
|
2
|
|
|
2
|
|
4
|
my( $cp ) = @_; |
1019
|
|
|
|
|
|
|
|
1020
|
2
|
|
|
|
|
4
|
$cp->filled(<<'EOF'); |
1021
|
|
|
|
|
|
|
The 'name' argument for identifier_presentation() is empty or undef. |
1022
|
|
|
|
|
|
|
EOF |
1023
|
2
|
|
|
|
|
2
|
return; |
1024
|
|
|
|
|
|
|
} |
1025
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
sub identifier_presentation { |
1027
|
420
|
|
|
420
|
1
|
905
|
my( $class, $name ) = @_; |
1028
|
|
|
|
|
|
|
|
1029
|
420
|
100
|
66
|
|
|
1717
|
error 'missing_identifier' |
1030
|
|
|
|
|
|
|
if not( defined $name ) |
1031
|
|
|
|
|
|
|
or not( length $name ); |
1032
|
|
|
|
|
|
|
|
1033
|
418
|
|
|
|
|
826
|
$name =~ s/ _ / /xg; |
1034
|
418
|
|
|
|
|
1203
|
$name =~ s{ ([[:lower:]]) ([[:upper:]]) }{ "$1 $2" }xge; |
|
3
|
|
|
|
|
10
|
|
1035
|
418
|
|
|
|
|
743
|
$name = lc $name; |
1036
|
|
|
|
|
|
|
|
1037
|
418
|
|
|
|
|
1205
|
return $name; |
1038
|
|
|
|
|
|
|
} |
1039
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
sub header { |
1041
|
871
|
|
|
871
|
1
|
913
|
my( $self, $title ) = @_; |
1042
|
|
|
|
|
|
|
|
1043
|
871
|
100
|
|
|
|
1368
|
if ( defined $title ) { |
1044
|
|
|
|
|
|
|
|
1045
|
757
|
100
|
|
|
|
1614
|
return '' |
1046
|
|
|
|
|
|
|
if not length $title; |
1047
|
|
|
|
|
|
|
} |
1048
|
|
|
|
|
|
|
else { |
1049
|
|
|
|
|
|
|
|
1050
|
114
|
|
|
|
|
3012
|
$title = $self->section_title; |
1051
|
|
|
|
|
|
|
} |
1052
|
|
|
|
|
|
|
|
1053
|
861
|
|
|
|
|
23935
|
my $header |
1054
|
|
|
|
|
|
|
= (' ' x $self->header_indent) |
1055
|
|
|
|
|
|
|
. "*** ${title} ***$NEWLINE"; |
1056
|
|
|
|
|
|
|
|
1057
|
861
|
|
|
|
|
1485
|
return $header; |
1058
|
|
|
|
|
|
|
} |
1059
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
sub banner { |
1061
|
419
|
|
|
419
|
1
|
522
|
my( $self ) = @_; |
1062
|
|
|
|
|
|
|
|
1063
|
419
|
|
|
|
|
10812
|
my $standout = ('~' x $self->columns) . $NEWLINE; |
1064
|
|
|
|
|
|
|
|
1065
|
419
|
|
|
|
|
10958
|
my $banner |
1066
|
|
|
|
|
|
|
= $standout |
1067
|
|
|
|
|
|
|
. $self->banner_title |
1068
|
|
|
|
|
|
|
. ' << ' |
1069
|
|
|
|
|
|
|
. $self->identifier_presentation( $self->handler_name ) |
1070
|
|
|
|
|
|
|
. ' >>' |
1071
|
|
|
|
|
|
|
. $NEWLINE |
1072
|
|
|
|
|
|
|
. $standout; |
1073
|
|
|
|
|
|
|
|
1074
|
419
|
|
|
|
|
755
|
return $banner; |
1075
|
|
|
|
|
|
|
} |
1076
|
|
|
|
|
|
|
|
1077
|
|
|
|
|
|
|
sub synopsis { |
1078
|
31
|
|
|
31
|
1
|
110
|
my( $self, @tag_value_pairs ) = @_; |
1079
|
|
|
|
|
|
|
|
1080
|
31
|
100
|
|
|
|
111
|
error 'odd_synopsis_augmentation', @tag_value_pairs |
1081
|
|
|
|
|
|
|
if @tag_value_pairs % 2; |
1082
|
|
|
|
|
|
|
|
1083
|
30
|
|
|
|
|
52
|
my $buffer = ''; |
1084
|
30
|
|
|
|
|
89
|
my $fd = _open_string_as_file( \$buffer ); |
1085
|
|
|
|
|
|
|
|
1086
|
30
|
|
|
|
|
46
|
eval { |
1087
|
30
|
|
|
|
|
868
|
pod2usage( -input => $self->pod_filename, |
1088
|
|
|
|
|
|
|
-output => $fd, |
1089
|
|
|
|
|
|
|
-exitval => 'NOEXIT', |
1090
|
|
|
|
|
|
|
-verbose => 0, |
1091
|
|
|
|
|
|
|
@tag_value_pairs ); |
1092
|
|
|
|
|
|
|
}; |
1093
|
|
|
|
|
|
|
|
1094
|
30
|
100
|
|
|
|
5005748
|
if ($EVAL_ERROR) { |
1095
|
|
|
|
|
|
|
|
1096
|
1
|
|
|
|
|
1
|
my $ignore = print {$fd} <<"EOF"; |
|
1
|
|
|
|
|
2
|
|
1097
|
1
|
|
|
|
|
24
|
Unable to create synopsis section from file '@{[ $self->pod_filename ]}': |
1098
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
$EVAL_ERROR |
1100
|
|
|
|
|
|
|
EOF |
1101
|
|
|
|
|
|
|
} |
1102
|
|
|
|
|
|
|
|
1103
|
30
|
|
|
|
|
135
|
_close_string_file( $fd ); |
1104
|
|
|
|
|
|
|
|
1105
|
30
|
|
|
|
|
116
|
$self->fixed( $buffer, 'Synopsis' ); |
1106
|
30
|
|
|
|
|
146
|
return; |
1107
|
|
|
|
|
|
|
} |
1108
|
|
|
|
|
|
|
|
1109
|
|
|
|
|
|
|
sub _open_string_as_file { |
1110
|
30
|
|
|
30
|
|
36
|
my( $string_ref ) = @_; |
1111
|
|
|
|
|
|
|
|
1112
|
30
|
50
|
|
187
|
|
795
|
open my( $fd ), '>', $string_ref |
|
4
|
|
|
|
|
26
|
|
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
29
|
|
1113
|
|
|
|
|
|
|
or error 'cannot_open_string'; |
1114
|
|
|
|
|
|
|
|
1115
|
30
|
|
|
|
|
4055
|
return $fd; |
1116
|
|
|
|
|
|
|
} |
1117
|
|
|
|
|
|
|
|
1118
|
|
|
|
|
|
|
sub _cp_cannot_open_string { |
1119
|
1
|
|
|
1
|
|
1
|
my( $cp ) = @_; |
1120
|
|
|
|
|
|
|
|
1121
|
1
|
|
|
|
|
3
|
$cp->filled( <<"EOF" ); |
1122
|
|
|
|
|
|
|
Unable to create a file descriptor using a string as the storage medium. |
1123
|
|
|
|
|
|
|
EOF |
1124
|
1
|
|
|
|
|
3
|
$cp->errno_section; |
1125
|
1
|
|
|
|
|
1
|
return; |
1126
|
|
|
|
|
|
|
} |
1127
|
|
|
|
|
|
|
|
1128
|
|
|
|
|
|
|
sub _close_string_file { |
1129
|
30
|
|
|
30
|
|
59
|
my( $fd ) = @_; |
1130
|
|
|
|
|
|
|
|
1131
|
30
|
50
|
|
|
|
150
|
close $fd |
1132
|
|
|
|
|
|
|
or error 'cannot_close_string'; |
1133
|
|
|
|
|
|
|
|
1134
|
30
|
|
|
|
|
98
|
return; |
1135
|
|
|
|
|
|
|
} |
1136
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
sub _cp_cannot_close_string { |
1138
|
1
|
|
|
1
|
|
2
|
my( $cp ) = @_; |
1139
|
|
|
|
|
|
|
|
1140
|
1
|
|
|
|
|
3
|
$cp->filled( <<"EOF" ); |
1141
|
|
|
|
|
|
|
Unable to close a file-descriptor that points to a string buffer as the |
1142
|
|
|
|
|
|
|
storage medium. |
1143
|
|
|
|
|
|
|
EOF |
1144
|
1
|
|
|
|
|
3
|
$cp->errno_section; |
1145
|
1
|
|
|
|
|
1
|
return; |
1146
|
|
|
|
|
|
|
} |
1147
|
|
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
sub _cp_odd_synopsis_augmentation { |
1149
|
1
|
|
|
1
|
|
3
|
my( $cp, @tag_value_pairs ) = @_; |
1150
|
|
|
|
|
|
|
|
1151
|
1
|
|
|
|
|
2
|
my $tv_report = ''; |
1152
|
1
|
|
|
|
|
19
|
while( @tag_value_pairs >= 2 ) { |
1153
|
|
|
|
|
|
|
|
1154
|
2
|
|
|
|
|
5
|
my( $t, $v ) = splice @tag_value_pairs, 0, 2; |
1155
|
|
|
|
|
|
|
|
1156
|
2
|
|
|
|
|
7
|
$tv_report .= "$t => $v" . $NEWLINE; |
1157
|
|
|
|
|
|
|
} |
1158
|
|
|
|
|
|
|
|
1159
|
1
|
|
|
|
|
2
|
$tv_report .= "$tag_value_pairs[0] =>" . $NEWLINE; |
1160
|
|
|
|
|
|
|
|
1161
|
1
|
|
|
|
|
5
|
$cp->filled( <<"EOF" ); |
1162
|
|
|
|
|
|
|
The synopsis() method allows users to supplement pod2usage() arguments |
1163
|
|
|
|
|
|
|
with tag-value pairs. The supplied arguments did not come in pairs; there |
1164
|
|
|
|
|
|
|
are an odd number. |
1165
|
|
|
|
|
|
|
|
1166
|
|
|
|
|
|
|
$tv_report |
1167
|
|
|
|
|
|
|
EOF |
1168
|
1
|
|
|
|
|
2
|
return; |
1169
|
|
|
|
|
|
|
} |
1170
|
|
|
|
|
|
|
|
1171
|
|
|
|
|
|
|
sub usage { |
1172
|
5
|
|
|
5
|
1
|
16
|
my( $self ) = @_; |
1173
|
|
|
|
|
|
|
|
1174
|
5
|
|
|
|
|
11
|
for(my $index = $self->_find_proxy_frame(); 1; ++$index ) { |
1175
|
|
|
|
|
|
|
|
1176
|
13
|
|
|
|
|
21
|
my( $subr ) = (caller $index)[ $CALLER_SUBROUTINE ]; |
1177
|
|
|
|
|
|
|
|
1178
|
13
|
100
|
|
|
|
764
|
error 'no_usage_documentation', $self |
1179
|
|
|
|
|
|
|
if not defined $subr; |
1180
|
|
|
|
|
|
|
|
1181
|
|
|
|
|
|
|
#----- Discard any package qualifiers |
1182
|
12
|
|
|
|
|
45
|
$subr =~ s/ \A .* :: //x; |
1183
|
|
|
|
|
|
|
|
1184
|
12
|
|
|
|
|
15
|
my $handler = 'usage_' . $subr; |
1185
|
|
|
|
|
|
|
|
1186
|
12
|
|
|
|
|
21
|
my $where = $self->_locate_handler( $handler ); |
1187
|
|
|
|
|
|
|
|
1188
|
|
|
|
|
|
|
next |
1189
|
12
|
100
|
|
|
|
21
|
if not $where; |
1190
|
|
|
|
|
|
|
|
1191
|
4
|
|
|
|
|
10
|
$where->( $self ); |
1192
|
4
|
|
|
|
|
8
|
last; |
1193
|
|
|
|
|
|
|
} |
1194
|
|
|
|
|
|
|
|
1195
|
4
|
|
|
|
|
4
|
return; |
1196
|
|
|
|
|
|
|
} |
1197
|
|
|
|
|
|
|
|
1198
|
|
|
|
|
|
|
sub _cp_no_usage_documentation { |
1199
|
1
|
|
|
1
|
|
2
|
my( $cp, $original_cp ) = @_; |
1200
|
|
|
|
|
|
|
|
1201
|
1
|
|
|
|
|
4
|
$cp->filled(<<"EOF"); |
1202
|
|
|
|
|
|
|
There was an error. The developers caught the error and attempted to |
1203
|
|
|
|
|
|
|
describe it. Part of the description was supposed to be provided by a |
1204
|
|
|
|
|
|
|
"usage" subroutine. Unfortunately they forgot to define the usage |
1205
|
|
|
|
|
|
|
subroutine. Now there are two errors. You shoud complain! |
1206
|
|
|
|
|
|
|
EOF |
1207
|
|
|
|
|
|
|
|
1208
|
1
|
|
|
|
|
22
|
my $prefix = $original_cp->handler_prefix; |
1209
|
|
|
|
|
|
|
|
1210
|
1
|
|
50
|
|
|
6
|
$prefix //= '(undef)'; |
1211
|
|
|
|
|
|
|
|
1212
|
1
|
|
|
|
|
2
|
$cp->fixed(<<"EOF", 'Missing Handler - Secondary Error'); |
1213
|
1
|
|
|
|
|
30
|
handler_pkgs: @{[ join ' : ', $original_cp->list_handler_pkgs ]} |
1214
|
|
|
|
|
|
|
handler_prefix: $prefix |
1215
|
|
|
|
|
|
|
EOF |
1216
|
|
|
|
|
|
|
|
1217
|
1
|
|
|
|
|
4
|
$cp->_describe_primary_error( $original_cp ); |
1218
|
1
|
|
|
|
|
2
|
return; |
1219
|
|
|
|
|
|
|
} |
1220
|
|
|
|
|
|
|
|
1221
|
|
|
|
|
|
|
BEGIN{ |
1222
|
43
|
|
|
43
|
|
53642
|
Readonly::Scalar my $ONE_BYTE => 8; |
1223
|
43
|
|
|
|
|
912
|
Readonly::Scalar my $SIGNAL_MASK => 0x7F; |
1224
|
43
|
|
|
|
|
591
|
Readonly::Scalar my $CORE_DUMP => 0x80; |
1225
|
|
|
|
|
|
|
|
1226
|
|
|
|
|
|
|
sub decipher_child_error { |
1227
|
256
|
|
|
256
|
1
|
1430
|
my( $cp ) = shift; |
1228
|
|
|
|
|
|
|
|
1229
|
256
|
50
|
33
|
|
|
8093
|
my $child_error = ( @_ and defined( $_[0] ) and $_[0] =~ /\A \d+ \z/x ) |
1230
|
|
|
|
|
|
|
? shift |
1231
|
|
|
|
|
|
|
: $cp->child_error; |
1232
|
|
|
|
|
|
|
|
1233
|
256
|
100
|
|
|
|
598
|
if ( 0 == $child_error ) { |
1234
|
|
|
|
|
|
|
|
1235
|
1
|
|
|
|
|
5
|
$cp->filled( 'The child process completed normally (exit code 0).', |
1236
|
|
|
|
|
|
|
'Process Succeeded' ); |
1237
|
1
|
|
|
|
|
2
|
return; |
1238
|
|
|
|
|
|
|
} |
1239
|
|
|
|
|
|
|
|
1240
|
255
|
|
|
|
|
418
|
my $signal = $child_error & $SIGNAL_MASK; |
1241
|
255
|
100
|
|
|
|
518
|
if ($signal) { |
1242
|
|
|
|
|
|
|
|
1243
|
254
|
|
|
|
|
8436
|
my @names = split ' ', $Config{sig_name}; |
1244
|
254
|
|
|
|
|
9091
|
my @nums = split ' ', $Config{sig_num}; |
1245
|
|
|
|
|
|
|
|
1246
|
254
|
|
|
|
|
904
|
my %by_num; |
1247
|
254
|
|
|
|
|
8508
|
@by_num{ @nums } = @names; |
1248
|
|
|
|
|
|
|
|
1249
|
254
|
|
|
|
|
450
|
my $sig_name = $by_num{ $signal }; |
1250
|
|
|
|
|
|
|
|
1251
|
254
|
100
|
|
|
|
1298
|
my $msg |
|
|
100
|
|
|
|
|
|
1252
|
|
|
|
|
|
|
= 'The child process was terminated by ' |
1253
|
|
|
|
|
|
|
. ((defined $sig_name) |
1254
|
|
|
|
|
|
|
? "SIG$sig_name (signal $signal)." |
1255
|
|
|
|
|
|
|
: "signal $signal.") |
1256
|
|
|
|
|
|
|
. (($child_error & $CORE_DUMP) |
1257
|
|
|
|
|
|
|
? ' There was a core dump.' |
1258
|
|
|
|
|
|
|
: ''); |
1259
|
|
|
|
|
|
|
|
1260
|
254
|
|
|
|
|
771
|
$cp->filled( $msg, 'Process terminated by signal' ); |
1261
|
254
|
|
|
|
|
4878
|
return; |
1262
|
|
|
|
|
|
|
} |
1263
|
|
|
|
|
|
|
|
1264
|
1
|
|
|
|
|
3
|
my $exit_code = $child_error >> $ONE_BYTE; |
1265
|
|
|
|
|
|
|
|
1266
|
1
|
|
|
|
|
7
|
$cp->filled( "The child process terminated with exit code $exit_code.", |
1267
|
|
|
|
|
|
|
'Process returns failing status' ); |
1268
|
1
|
|
|
|
|
1
|
return; |
1269
|
|
|
|
|
|
|
} |
1270
|
|
|
|
|
|
|
} |
1271
|
|
|
|
|
|
|
|
1272
|
|
|
|
|
|
|
sub filename { |
1273
|
2
|
|
|
2
|
1
|
13
|
my( $cp, $file, $title ) = @_; |
1274
|
|
|
|
|
|
|
|
1275
|
2
|
100
|
|
|
|
6
|
$title = 'Filename' |
1276
|
|
|
|
|
|
|
if not defined $title; |
1277
|
|
|
|
|
|
|
|
1278
|
2
|
|
|
|
|
8
|
$cp->_abs_path_section( $file, $title ); |
1279
|
2
|
|
|
|
|
3
|
return; |
1280
|
|
|
|
|
|
|
} |
1281
|
|
|
|
|
|
|
|
1282
|
|
|
|
|
|
|
sub directory { |
1283
|
2
|
|
|
2
|
1
|
12
|
my( $cp, $dir, $title ) = @_; |
1284
|
|
|
|
|
|
|
|
1285
|
2
|
100
|
|
|
|
7
|
$title = 'Directory' |
1286
|
|
|
|
|
|
|
if not defined $title; |
1287
|
|
|
|
|
|
|
|
1288
|
2
|
|
|
|
|
6
|
$cp->_abs_path_section( $dir, $title ); |
1289
|
2
|
|
|
|
|
4
|
return; |
1290
|
|
|
|
|
|
|
} |
1291
|
|
|
|
|
|
|
|
1292
|
|
|
|
|
|
|
sub _abs_path_section { |
1293
|
4
|
|
|
4
|
|
7
|
my( $cp, $entry, $title ) = @_; |
1294
|
|
|
|
|
|
|
|
1295
|
4
|
|
|
|
|
4
|
my $path; |
1296
|
|
|
|
|
|
|
|
1297
|
|
|
|
|
|
|
#----- |
1298
|
|
|
|
|
|
|
# On *nix abs_path() appears to return undef if it has trouble. On |
1299
|
|
|
|
|
|
|
# Windows it appears to throw. Docs are ambiguous. |
1300
|
|
|
|
|
|
|
#----- |
1301
|
4
|
|
|
|
|
5
|
eval{ $path = abs_path( $entry ); }; |
|
4
|
|
|
|
|
132
|
|
1302
|
|
|
|
|
|
|
|
1303
|
4
|
100
|
66
|
|
|
21
|
$path = $entry |
1304
|
|
|
|
|
|
|
if not( defined $path ) |
1305
|
|
|
|
|
|
|
or $EVAL_ERROR; |
1306
|
|
|
|
|
|
|
|
1307
|
4
|
|
|
|
|
10
|
$cp->fixed( $path, $title ); |
1308
|
|
|
|
|
|
|
|
1309
|
4
|
|
|
|
|
3
|
return; |
1310
|
|
|
|
|
|
|
} |
1311
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
sub errno_section { |
1313
|
6
|
|
|
6
|
1
|
19
|
my( $cp, $title ) = @_; |
1314
|
|
|
|
|
|
|
|
1315
|
6
|
|
|
|
|
138
|
my $string_errno = $cp->string_errno; |
1316
|
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
return |
1318
|
6
|
100
|
66
|
|
|
23
|
if not( defined $string_errno ) |
1319
|
|
|
|
|
|
|
or not( length $string_errno ); |
1320
|
|
|
|
|
|
|
|
1321
|
2
|
100
|
|
|
|
4
|
$title = 'System Diagnostic' |
1322
|
|
|
|
|
|
|
if not defined $title; |
1323
|
|
|
|
|
|
|
|
1324
|
2
|
|
|
|
|
5
|
$cp->filled( $string_errno, $title ); |
1325
|
2
|
|
|
|
|
2
|
return; |
1326
|
|
|
|
|
|
|
} |
1327
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
sub render_message { |
1329
|
424
|
|
|
424
|
1
|
613
|
my( $self ) = @_; |
1330
|
|
|
|
|
|
|
|
1331
|
424
|
100
|
|
|
|
12525
|
return Dump( $self ) |
1332
|
|
|
|
|
|
|
if $self->as_yaml; |
1333
|
|
|
|
|
|
|
|
1334
|
420
|
|
|
|
|
1137
|
my $buffer = $self->banner; |
1335
|
|
|
|
|
|
|
|
1336
|
420
|
|
|
|
|
15295
|
my @sections = $self->list_sections; |
1337
|
420
|
|
|
|
|
814
|
foreach my $s (@sections) { |
1338
|
|
|
|
|
|
|
|
1339
|
875
|
|
|
|
|
973
|
my( $meth, @args ) = @{ $s }; |
|
875
|
|
|
|
|
1702
|
|
1340
|
|
|
|
|
|
|
|
1341
|
875
|
|
|
|
|
2667
|
$buffer .= $self->$meth( @args ); |
1342
|
|
|
|
|
|
|
} |
1343
|
420
|
|
|
|
|
3783
|
return $buffer; |
1344
|
|
|
|
|
|
|
} |
1345
|
|
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
sub call { |
1347
|
528
|
|
|
528
|
1
|
951
|
my( $self, $handler, @args ) = @_; |
1348
|
|
|
|
|
|
|
|
1349
|
528
|
|
|
|
|
1259
|
my $where = $self->_locate_handler( $handler ); |
1350
|
|
|
|
|
|
|
|
1351
|
528
|
100
|
|
|
|
1165
|
error 'embarrassed_developers', $self, $handler |
1352
|
|
|
|
|
|
|
if not $where; |
1353
|
|
|
|
|
|
|
|
1354
|
522
|
|
|
|
|
1609
|
$where->( $self, @args ); |
1355
|
|
|
|
|
|
|
|
1356
|
462
|
|
|
|
|
5870
|
return; |
1357
|
|
|
|
|
|
|
} |
1358
|
|
|
|
|
|
|
|
1359
|
|
|
|
|
|
|
sub _locate_handler { |
1360
|
540
|
|
|
540
|
|
630
|
my( $self, $handler_name ) = @_; |
1361
|
|
|
|
|
|
|
|
1362
|
540
|
|
|
|
|
489
|
my $coderef; |
1363
|
|
|
|
|
|
|
|
1364
|
540
|
100
|
|
|
|
1448
|
if ($handler_name =~ /\A [*] ( .+ ) [*] \z/x) { |
1365
|
|
|
|
|
|
|
|
1366
|
13
|
|
|
|
|
22
|
my $builtin = $1; |
1367
|
13
|
|
|
|
|
65
|
$coderef = $self->can( '_builtin_' . $builtin ); |
1368
|
|
|
|
|
|
|
} |
1369
|
|
|
|
|
|
|
else { |
1370
|
|
|
|
|
|
|
|
1371
|
527
|
|
|
|
|
14332
|
my $handler_prefix = $self->handler_prefix; |
1372
|
|
|
|
|
|
|
|
1373
|
527
|
100
|
|
|
|
2025
|
my @prefixes = (defined $handler_prefix) |
1374
|
|
|
|
|
|
|
? ( $handler_prefix ) |
1375
|
|
|
|
|
|
|
: ( '_cp_', '_', '' ); |
1376
|
|
|
|
|
|
|
|
1377
|
527
|
|
|
|
|
19273
|
PKG: foreach my $pkg ($self->list_handler_pkgs) { |
1378
|
|
|
|
|
|
|
|
1379
|
529
|
|
|
|
|
740
|
foreach my $pre (@prefixes) { |
1380
|
|
|
|
|
|
|
|
1381
|
1474
|
|
|
|
|
6528
|
$coderef = $pkg->can( $pre . $handler_name ); |
1382
|
|
|
|
|
|
|
|
1383
|
|
|
|
|
|
|
last PKG |
1384
|
1474
|
100
|
|
|
|
3455
|
if $coderef; |
1385
|
|
|
|
|
|
|
} |
1386
|
|
|
|
|
|
|
} |
1387
|
|
|
|
|
|
|
} |
1388
|
|
|
|
|
|
|
|
1389
|
540
|
|
|
|
|
1165
|
return $coderef; |
1390
|
|
|
|
|
|
|
} |
1391
|
|
|
|
|
|
|
|
1392
|
|
|
|
|
|
|
sub _cp_embarrassed_developers { |
1393
|
6
|
|
|
6
|
|
8
|
my( $cp, $original_cp, $handler ) = @_; |
1394
|
|
|
|
|
|
|
|
1395
|
6
|
|
|
|
|
11
|
$cp->filled(<<"EOF"); |
1396
|
|
|
|
|
|
|
There was an error. The developers caught the error and attempted to |
1397
|
|
|
|
|
|
|
pass diagnosis off to a handler. Unfortunately they forgot to define |
1398
|
|
|
|
|
|
|
the handler. Now there are two errors. You shoud complain! |
1399
|
|
|
|
|
|
|
EOF |
1400
|
|
|
|
|
|
|
|
1401
|
6
|
|
|
|
|
138
|
my $prefix = $original_cp->handler_prefix; |
1402
|
|
|
|
|
|
|
|
1403
|
6
|
|
100
|
|
|
11
|
$prefix //= '(undef)'; |
1404
|
|
|
|
|
|
|
|
1405
|
6
|
100
|
|
|
|
12
|
$prefix = q('') |
1406
|
|
|
|
|
|
|
if not length $prefix; |
1407
|
|
|
|
|
|
|
|
1408
|
6
|
|
|
|
|
11
|
$cp->fixed(<<"EOF", 'Missing Handler - Secondary Error'); |
1409
|
6
|
|
|
|
|
165
|
handler_name: $handler |
1410
|
|
|
|
|
|
|
handler_pkgs: @{[ join ' : ', $original_cp->list_handler_pkgs ]} |
1411
|
|
|
|
|
|
|
handler_prefix: $prefix |
1412
|
|
|
|
|
|
|
EOF |
1413
|
|
|
|
|
|
|
|
1414
|
6
|
|
|
|
|
15
|
$cp->_describe_primary_error( $original_cp ); |
1415
|
6
|
|
|
|
|
5
|
return; |
1416
|
|
|
|
|
|
|
} |
1417
|
|
|
|
|
|
|
|
1418
|
|
|
|
|
|
|
sub _builtin_internal_error { |
1419
|
8
|
|
|
8
|
|
10
|
my( $cp, @args ) = @_; |
1420
|
|
|
|
|
|
|
|
1421
|
8
|
100
|
|
|
|
25
|
$cp->filled( "@args" ) |
1422
|
|
|
|
|
|
|
if @args; |
1423
|
|
|
|
|
|
|
|
1424
|
8
|
|
|
|
|
22
|
$cp->contact_maintainer; |
1425
|
|
|
|
|
|
|
|
1426
|
8
|
|
|
|
|
7
|
return; |
1427
|
|
|
|
|
|
|
} |
1428
|
|
|
|
|
|
|
|
1429
|
|
|
|
|
|
|
sub _builtin_assertion_failure { |
1430
|
5
|
|
|
5
|
|
8
|
my( $cp, $description, $hashref ) = @_; |
1431
|
|
|
|
|
|
|
|
1432
|
5
|
|
|
|
|
6
|
my $boilerplate = <<"EOF"; |
1433
|
|
|
|
|
|
|
An assertion has failed. This indicates that the internal state of |
1434
|
|
|
|
|
|
|
the program is corrupt. |
1435
|
|
|
|
|
|
|
EOF |
1436
|
|
|
|
|
|
|
|
1437
|
5
|
100
|
100
|
|
|
25
|
$boilerplate .= $NEWLINE . $description |
1438
|
|
|
|
|
|
|
if defined( $description ) |
1439
|
|
|
|
|
|
|
and length( $description ); |
1440
|
|
|
|
|
|
|
|
1441
|
5
|
|
|
|
|
12
|
$cp->filled( $boilerplate ); |
1442
|
|
|
|
|
|
|
|
1443
|
5
|
|
|
|
|
10
|
$cp->contact_maintainer; |
1444
|
|
|
|
|
|
|
|
1445
|
5
|
100
|
100
|
|
|
17
|
if (defined( $hashref ) and keys %{ $hashref }) { |
|
2
|
|
|
|
|
8
|
|
1446
|
|
|
|
|
|
|
|
1447
|
1
|
|
|
|
|
88
|
my $yaml = Dump( $hashref ); |
1448
|
|
|
|
|
|
|
|
1449
|
1
|
|
|
|
|
5
|
$cp->fixed( $yaml, 'Salient State (YAML)' ); |
1450
|
|
|
|
|
|
|
} |
1451
|
|
|
|
|
|
|
|
1452
|
5
|
|
|
|
|
116
|
$cp->context( 'confess' ); |
1453
|
|
|
|
|
|
|
|
1454
|
5
|
|
|
|
|
7
|
return; |
1455
|
|
|
|
|
|
|
} |
1456
|
|
|
|
|
|
|
|
1457
|
|
|
|
|
|
|
sub contact_maintainer { |
1458
|
31
|
|
|
31
|
1
|
52
|
my( $cp ) = @_; |
1459
|
|
|
|
|
|
|
|
1460
|
31
|
|
|
|
|
885
|
my $maintainer = $cp->maintainer; |
1461
|
|
|
|
|
|
|
|
1462
|
31
|
100
|
|
|
|
85
|
$cp->fixed( $maintainer, 'Please contact the maintainer' ) |
1463
|
|
|
|
|
|
|
if length $maintainer; |
1464
|
|
|
|
|
|
|
|
1465
|
31
|
|
|
|
|
42
|
return; |
1466
|
|
|
|
|
|
|
} |
1467
|
|
|
|
|
|
|
|
1468
|
|
|
|
|
|
|
BEGIN { |
1469
|
|
|
|
|
|
|
|
1470
|
|
|
|
|
|
|
#----- |
1471
|
|
|
|
|
|
|
# The real intent of this eval is to add another frame to the |
1472
|
|
|
|
|
|
|
# callstack so that create_proxy() installs error() into the |
1473
|
|
|
|
|
|
|
# Carp::Proxy package. |
1474
|
|
|
|
|
|
|
#----- |
1475
|
43
|
|
|
43
|
|
33671
|
eval { |
1476
|
43
|
|
|
|
|
448
|
__PACKAGE__->import( 'error', |
1477
|
|
|
|
|
|
|
{ |
1478
|
|
|
|
|
|
|
banner_title => 'Oops', |
1479
|
|
|
|
|
|
|
context => 'internals', |
1480
|
|
|
|
|
|
|
}); |
1481
|
|
|
|
|
|
|
}; |
1482
|
|
|
|
|
|
|
|
1483
|
|
|
|
|
|
|
## no critic( ErrorHandling::RequireCarping ) |
1484
|
43
|
50
|
|
|
|
3888
|
die $EVAL_ERROR if $EVAL_ERROR; |
1485
|
|
|
|
|
|
|
} |
1486
|
|
|
|
|
|
|
|
1487
|
|
|
|
|
|
|
|
1488
|
|
|
|
|
|
|
1; |
1489
|
|
|
|
|
|
|
|
1490
|
|
|
|
|
|
|
__END__ |
1491
|
|
|
|
|
|
|
|
1492
|
|
|
|
|
|
|
=pod |
1493
|
|
|
|
|
|
|
|
1494
|
|
|
|
|
|
|
=begin stopwords |
1495
|
|
|
|
|
|
|
|
1496
|
|
|
|
|
|
|
accessor |
1497
|
|
|
|
|
|
|
accessors |
1498
|
|
|
|
|
|
|
AnnoCPAN |
1499
|
|
|
|
|
|
|
arg |
1500
|
|
|
|
|
|
|
arg-checking |
1501
|
|
|
|
|
|
|
ArrayRef |
1502
|
|
|
|
|
|
|
ArrayRefs |
1503
|
|
|
|
|
|
|
boolean |
1504
|
|
|
|
|
|
|
boundarys |
1505
|
|
|
|
|
|
|
builtin |
1506
|
|
|
|
|
|
|
BUILTIN |
1507
|
|
|
|
|
|
|
callstack |
1508
|
|
|
|
|
|
|
camelCasedIdentifiers |
1509
|
|
|
|
|
|
|
CodeRef |
1510
|
|
|
|
|
|
|
CPAN |
1511
|
|
|
|
|
|
|
CPAN's |
1512
|
|
|
|
|
|
|
customizable |
1513
|
|
|
|
|
|
|
dereferences |
1514
|
|
|
|
|
|
|
filename |
1515
|
|
|
|
|
|
|
HashRef |
1516
|
|
|
|
|
|
|
hashref |
1517
|
|
|
|
|
|
|
initializations |
1518
|
|
|
|
|
|
|
invoker |
1519
|
|
|
|
|
|
|
invoker-upward |
1520
|
|
|
|
|
|
|
Liebert |
1521
|
|
|
|
|
|
|
logfile |
1522
|
|
|
|
|
|
|
multi-line |
1523
|
|
|
|
|
|
|
parameterized |
1524
|
|
|
|
|
|
|
perldoc |
1525
|
|
|
|
|
|
|
perlvar |
1526
|
|
|
|
|
|
|
prepended |
1527
|
|
|
|
|
|
|
Proxys |
1528
|
|
|
|
|
|
|
regex |
1529
|
|
|
|
|
|
|
repeatability |
1530
|
|
|
|
|
|
|
runtime |
1531
|
|
|
|
|
|
|
rw |
1532
|
|
|
|
|
|
|
stackframe |
1533
|
|
|
|
|
|
|
stackframes |
1534
|
|
|
|
|
|
|
Stackframes |
1535
|
|
|
|
|
|
|
stacktrace |
1536
|
|
|
|
|
|
|
stacktraces |
1537
|
|
|
|
|
|
|
STDERR |
1538
|
|
|
|
|
|
|
stringification |
1539
|
|
|
|
|
|
|
tradeoff |
1540
|
|
|
|
|
|
|
undef |
1541
|
|
|
|
|
|
|
whitespace |
1542
|
|
|
|
|
|
|
YAML |
1543
|
|
|
|
|
|
|
|
1544
|
|
|
|
|
|
|
=end stopwords |
1545
|
|
|
|
|
|
|
|
1546
|
|
|
|
|
|
|
=head1 NAME |
1547
|
|
|
|
|
|
|
|
1548
|
|
|
|
|
|
|
Carp::Proxy - Diagnostic delegation |
1549
|
|
|
|
|
|
|
|
1550
|
|
|
|
|
|
|
=head1 SYNOPSIS |
1551
|
|
|
|
|
|
|
|
1552
|
|
|
|
|
|
|
use Carp::Proxy; |
1553
|
|
|
|
|
|
|
|
1554
|
|
|
|
|
|
|
fatal 'handler_subroutine', @optional_arguments |
1555
|
|
|
|
|
|
|
if not $assertion; |
1556
|
|
|
|
|
|
|
|
1557
|
|
|
|
|
|
|
sub handler_subroutine { |
1558
|
|
|
|
|
|
|
my( $proxy_object, @optional_arguments ) = @_; |
1559
|
|
|
|
|
|
|
|
1560
|
|
|
|
|
|
|
$proxy_object->filled( 'explanation' ); |
1561
|
|
|
|
|
|
|
return; |
1562
|
|
|
|
|
|
|
} |
1563
|
|
|
|
|
|
|
|
1564
|
|
|
|
|
|
|
=head1 DESCRIPTION |
1565
|
|
|
|
|
|
|
|
1566
|
|
|
|
|
|
|
B<Carp::Proxy> is a framework for throwing exceptions. The goal is to |
1567
|
|
|
|
|
|
|
couple the small lexical footprint of the B<die()> statement with |
1568
|
|
|
|
|
|
|
support for comprehensive error messages. Good diagnostics pay for |
1569
|
|
|
|
|
|
|
themselves; let's make them easier to produce. |
1570
|
|
|
|
|
|
|
|
1571
|
|
|
|
|
|
|
Error messages in Perl are commonly coded with idioms like: |
1572
|
|
|
|
|
|
|
|
1573
|
|
|
|
|
|
|
die 'explanation' |
1574
|
|
|
|
|
|
|
if not $assertion; |
1575
|
|
|
|
|
|
|
|
1576
|
|
|
|
|
|
|
The idiom is attractive when the explanation is simple. If an |
1577
|
|
|
|
|
|
|
explanation grows to more than a few words, or if it requires |
1578
|
|
|
|
|
|
|
calculation, then the surrounding flow becomes disrupted. The |
1579
|
|
|
|
|
|
|
solution, of course, is to offload failing assertions to a subroutine. |
1580
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
Subroutines that perform diagnosis, compose error messages and throw |
1582
|
|
|
|
|
|
|
exceptions tend to have repeated code at the beginning and end, with |
1583
|
|
|
|
|
|
|
unique content somewhere in the middle. B<Carp::Proxy> proposes a |
1584
|
|
|
|
|
|
|
wrapper subroutine, called a Proxy, to factor out the repeated sections. |
1585
|
|
|
|
|
|
|
|
1586
|
|
|
|
|
|
|
fatal 'user_subroutine' |
1587
|
|
|
|
|
|
|
if not $assertion; |
1588
|
|
|
|
|
|
|
|
1589
|
|
|
|
|
|
|
Proxys, like B<fatal()>, serve as elaborate, customizable replacements |
1590
|
|
|
|
|
|
|
for B<warn()>, B<die()> and members of the B<Carp::> family like |
1591
|
|
|
|
|
|
|
B<confess()>. If we look at B<warn()>, B<die()>, B<confess()> and the |
1592
|
|
|
|
|
|
|
others, we notice that they are all just different variations on two themes: |
1593
|
|
|
|
|
|
|
|
1594
|
|
|
|
|
|
|
- Add locational context to a user-supplied message. |
1595
|
|
|
|
|
|
|
- Throw some kind of exception. |
1596
|
|
|
|
|
|
|
|
1597
|
|
|
|
|
|
|
B<Carp::Proxy> parameterizes the two themes into attributes of an |
1598
|
|
|
|
|
|
|
exception object that is created whenever a Proxy is called. The |
1599
|
|
|
|
|
|
|
Proxy passes the object to a user-defined "Handler" subroutine which |
1600
|
|
|
|
|
|
|
is responsible for constructing the diagnostic message. When the |
1601
|
|
|
|
|
|
|
Handler returns, the Proxy optionally adds "Context" (a stacktrace) to |
1602
|
|
|
|
|
|
|
the message and performs "Disposition", typically by calling B<die()>. |
1603
|
|
|
|
|
|
|
|
1604
|
|
|
|
|
|
|
When the object is constructed it captures the state of Perl's error |
1605
|
|
|
|
|
|
|
variables, for later examination by the Handler. The object provides |
1606
|
|
|
|
|
|
|
methods that aid in message composition. Attributes control message |
1607
|
|
|
|
|
|
|
formatting, stacktrace generation and how Disposition will be handled. |
1608
|
|
|
|
|
|
|
|
1609
|
|
|
|
|
|
|
The object overloads Perl's stringification operator with a message |
1610
|
|
|
|
|
|
|
rendering method, causing uncaught exceptions to be nicely formatted. |
1611
|
|
|
|
|
|
|
Exceptions that are caught can be modified and re-thrown. |
1612
|
|
|
|
|
|
|
|
1613
|
|
|
|
|
|
|
=head1 WE ARE THE 99% |
1614
|
|
|
|
|
|
|
|
1615
|
|
|
|
|
|
|
B<Carp::Proxy> has a long list of features, but getting started is easy. |
1616
|
|
|
|
|
|
|
All you need for most day-to-day work is the Proxy and two methods: |
1617
|
|
|
|
|
|
|
|
1618
|
|
|
|
|
|
|
fatal() The (default) Proxy. |
1619
|
|
|
|
|
|
|
filled() Auto-formatting message builder method. |
1620
|
|
|
|
|
|
|
fixed() Pre-formatted message builder method. |
1621
|
|
|
|
|
|
|
|
1622
|
|
|
|
|
|
|
Use B<fatal()> wherever you currently use B<die()>. Your Handler should |
1623
|
|
|
|
|
|
|
compose the diagnostic text using the L<filled()|/filled> and/or |
1624
|
|
|
|
|
|
|
L<fixed()|/fixed> methods. |
1625
|
|
|
|
|
|
|
|
1626
|
|
|
|
|
|
|
=head1 SAMPLE OUTPUT |
1627
|
|
|
|
|
|
|
|
1628
|
|
|
|
|
|
|
The formatted messages produced by the Proxy start off with a |
1629
|
|
|
|
|
|
|
"Banner". The Banner includes a title and the name of the Handler. |
1630
|
|
|
|
|
|
|
As the Banner is the first thing seen by users, it is helpful if the |
1631
|
|
|
|
|
|
|
Handler name conveys a terse description of the situation. |
1632
|
|
|
|
|
|
|
|
1633
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1634
|
|
|
|
|
|
|
Fatal: << cannot overwrite >> |
1635
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1636
|
|
|
|
|
|
|
|
1637
|
|
|
|
|
|
|
Following the Banner are a series of "Sections" containing paragraphs of |
1638
|
|
|
|
|
|
|
descriptive text. Each Section is introduced by a "Header" sub-title |
1639
|
|
|
|
|
|
|
that is wrapped in *** stars ***. |
1640
|
|
|
|
|
|
|
|
1641
|
|
|
|
|
|
|
*** Description *** |
1642
|
|
|
|
|
|
|
The destination file already exists. An attempt was made |
1643
|
|
|
|
|
|
|
to overwrite it, but the attempt failed. This might have |
1644
|
|
|
|
|
|
|
happened because of permission problems, or possibly if |
1645
|
|
|
|
|
|
|
the destination is not a file (i.e. a directory or link |
1646
|
|
|
|
|
|
|
or something else). |
1647
|
|
|
|
|
|
|
|
1648
|
|
|
|
|
|
|
Either remove the destination manually, or choose a |
1649
|
|
|
|
|
|
|
different destination. |
1650
|
|
|
|
|
|
|
|
1651
|
|
|
|
|
|
|
*** Destination Filename *** |
1652
|
|
|
|
|
|
|
/home/isaac/muse/content |
1653
|
|
|
|
|
|
|
|
1654
|
|
|
|
|
|
|
*** ls(1) output *** |
1655
|
|
|
|
|
|
|
-r--r--r-- 1 isaac users 21626 Aug 5 17:22 content |
1656
|
|
|
|
|
|
|
|
1657
|
|
|
|
|
|
|
*** System Diagnostic *** |
1658
|
|
|
|
|
|
|
Permission denied |
1659
|
|
|
|
|
|
|
|
1660
|
|
|
|
|
|
|
*** Stacktrace *** |
1661
|
|
|
|
|
|
|
fatal called from line 273 of /usr/bin/cantu |
1662
|
|
|
|
|
|
|
set_output called from line 244 of /usr/bin/cantu |
1663
|
|
|
|
|
|
|
main called from line 24 of /usr/bin/cantu |
1664
|
|
|
|
|
|
|
|
1665
|
|
|
|
|
|
|
Here is the corresponding Handler code. Note that most of the Handler's |
1666
|
|
|
|
|
|
|
body is dedicated to producing message content; there is very little |
1667
|
|
|
|
|
|
|
overhead. Handlers are easy to write. |
1668
|
|
|
|
|
|
|
|
1669
|
|
|
|
|
|
|
sub cannot_overwrite { |
1670
|
|
|
|
|
|
|
my( $cp, $filename ) = @_; |
1671
|
|
|
|
|
|
|
|
1672
|
|
|
|
|
|
|
$cp->filled(<<"EOF"); |
1673
|
|
|
|
|
|
|
The destination file already exists. An attempt was made to |
1674
|
|
|
|
|
|
|
overwrite it, but the attempt failed. This might have happened |
1675
|
|
|
|
|
|
|
because of permission problems, or possibly if the destination |
1676
|
|
|
|
|
|
|
is not a file (i.e. a directory or link or something else). |
1677
|
|
|
|
|
|
|
|
1678
|
|
|
|
|
|
|
Either remove the destination manually, or choose a different |
1679
|
|
|
|
|
|
|
destination. |
1680
|
|
|
|
|
|
|
EOF |
1681
|
|
|
|
|
|
|
$cp->filename( $filename, 'Destination Filename' ); |
1682
|
|
|
|
|
|
|
$cp->fixed( qx{ /bin/ls -ld $filename }, 'ls(1) output' ); |
1683
|
|
|
|
|
|
|
$cp->errno_section; |
1684
|
|
|
|
|
|
|
return; |
1685
|
|
|
|
|
|
|
} |
1686
|
|
|
|
|
|
|
|
1687
|
|
|
|
|
|
|
=head1 EXPORTS |
1688
|
|
|
|
|
|
|
|
1689
|
|
|
|
|
|
|
B<Carp::Proxy> defines an exception class. Depending on the arguments |
1690
|
|
|
|
|
|
|
supplied to B<use()>, B<Carp::Proxy> also generates Proxy subroutines |
1691
|
|
|
|
|
|
|
for export. The generation part is important: B<Carp::Proxy> |
1692
|
|
|
|
|
|
|
implements the B<import()> method as a function factory. |
1693
|
|
|
|
|
|
|
|
1694
|
|
|
|
|
|
|
Proxy customization is performed by supplying a HashRef of |
1695
|
|
|
|
|
|
|
B<attribute =E<gt> parameter> pairs for each desired Proxy. |
1696
|
|
|
|
|
|
|
The arguments to B<use()> or B<import()> look like this: |
1697
|
|
|
|
|
|
|
|
1698
|
|
|
|
|
|
|
proxy_name1 => |
1699
|
|
|
|
|
|
|
{ |
1700
|
|
|
|
|
|
|
attribute => parameter, |
1701
|
|
|
|
|
|
|
... |
1702
|
|
|
|
|
|
|
}, |
1703
|
|
|
|
|
|
|
|
1704
|
|
|
|
|
|
|
proxy_name2 => |
1705
|
|
|
|
|
|
|
{ |
1706
|
|
|
|
|
|
|
attribute => parameter, |
1707
|
|
|
|
|
|
|
... |
1708
|
|
|
|
|
|
|
}, |
1709
|
|
|
|
|
|
|
... |
1710
|
|
|
|
|
|
|
|
1711
|
|
|
|
|
|
|
If there is only one argument, i.e. a proxy-name key with no corresponding |
1712
|
|
|
|
|
|
|
value, then an empty HashRef, C<{}>, where all attributes assume defaults, |
1713
|
|
|
|
|
|
|
is implied. |
1714
|
|
|
|
|
|
|
|
1715
|
|
|
|
|
|
|
Here are some examples: |
1716
|
|
|
|
|
|
|
|
1717
|
|
|
|
|
|
|
#----- |
1718
|
|
|
|
|
|
|
# All three of these 'use' statements generate and export a |
1719
|
|
|
|
|
|
|
# Proxy named fatal() with defaults for all attributes. |
1720
|
|
|
|
|
|
|
#----- |
1721
|
|
|
|
|
|
|
use Carp::Proxy; |
1722
|
|
|
|
|
|
|
use Carp::Proxy 'fatal'; |
1723
|
|
|
|
|
|
|
use Carp::Proxy fatal => {}; |
1724
|
|
|
|
|
|
|
|
1725
|
|
|
|
|
|
|
#----- |
1726
|
|
|
|
|
|
|
# This statement is the same as all of the above, except |
1727
|
|
|
|
|
|
|
# that now the Proxy is named error() instead of fatal(). |
1728
|
|
|
|
|
|
|
#----- |
1729
|
|
|
|
|
|
|
use Carp::Proxy 'error'; |
1730
|
|
|
|
|
|
|
|
1731
|
|
|
|
|
|
|
#----- |
1732
|
|
|
|
|
|
|
# Here we export two proxys, oops() and warning(), each with |
1733
|
|
|
|
|
|
|
# different sets of attributes. |
1734
|
|
|
|
|
|
|
#----- |
1735
|
|
|
|
|
|
|
use Carp::Proxy oops => { context => 'internals' }, |
1736
|
|
|
|
|
|
|
warning => { banner_title => 'Warning', |
1737
|
|
|
|
|
|
|
disposition => 'warn' }; |
1738
|
|
|
|
|
|
|
|
1739
|
|
|
|
|
|
|
#----- No exports. Class definition only. |
1740
|
|
|
|
|
|
|
use Carp::Proxy (); |
1741
|
|
|
|
|
|
|
|
1742
|
|
|
|
|
|
|
The no-export form is desirable if you want the class definition for your |
1743
|
|
|
|
|
|
|
own purposes, or if Proxy attributes need to be established at runtime. |
1744
|
|
|
|
|
|
|
You can invoke L<import()|/import>, at any time, to build Proxy subroutines. |
1745
|
|
|
|
|
|
|
|
1746
|
|
|
|
|
|
|
use Carp::Proxy (); |
1747
|
|
|
|
|
|
|
... |
1748
|
|
|
|
|
|
|
Carp::Proxy->import( expire => { end_hook => $log_me }); |
1749
|
|
|
|
|
|
|
|
1750
|
|
|
|
|
|
|
=head1 PROXY INVOCATION |
1751
|
|
|
|
|
|
|
|
1752
|
|
|
|
|
|
|
Usage: |
1753
|
|
|
|
|
|
|
<proxy> $handler, @optional_arguments; |
1754
|
|
|
|
|
|
|
|
1755
|
|
|
|
|
|
|
The default L<proxy_name|/proxy_name> is C<fatal> so the typical |
1756
|
|
|
|
|
|
|
usage looks more like |
1757
|
|
|
|
|
|
|
|
1758
|
|
|
|
|
|
|
fatal $handler, @optional_arguments; |
1759
|
|
|
|
|
|
|
|
1760
|
|
|
|
|
|
|
I<$handler> is expected to be a string (NOT a CodeRef!) that names a |
1761
|
|
|
|
|
|
|
user-defined subroutine. |
1762
|
|
|
|
|
|
|
|
1763
|
|
|
|
|
|
|
The Proxy performs the following actions: |
1764
|
|
|
|
|
|
|
|
1765
|
|
|
|
|
|
|
=over 4 |
1766
|
|
|
|
|
|
|
|
1767
|
|
|
|
|
|
|
=item B<1 - Capture the Environment> |
1768
|
|
|
|
|
|
|
|
1769
|
|
|
|
|
|
|
Perl's error/status variables $ARG, $ERRNO, $CHILD_ERROR and $EVAL_ERROR |
1770
|
|
|
|
|
|
|
(also known as B<$_>, B<$!>, B<$?> and B<$@>, respectively) are all |
1771
|
|
|
|
|
|
|
captured as soon as possible to preserve their values for examination by |
1772
|
|
|
|
|
|
|
I<$handler>. |
1773
|
|
|
|
|
|
|
|
1774
|
|
|
|
|
|
|
=item B<2 - Create a Carp::Proxy object> |
1775
|
|
|
|
|
|
|
|
1776
|
|
|
|
|
|
|
The Proxy supplies settings for all the object's required attributes, |
1777
|
|
|
|
|
|
|
see L<ATTRIBUTES|/ATTRIBUTES>. The Proxy also |
1778
|
|
|
|
|
|
|
forwards initializations for any attributes supplied by the user (arguments |
1779
|
|
|
|
|
|
|
to B<use()> or L<import()|/import>). |
1780
|
|
|
|
|
|
|
|
1781
|
|
|
|
|
|
|
=item B<3 - Call begin_hook> |
1782
|
|
|
|
|
|
|
|
1783
|
|
|
|
|
|
|
The L<begin_hook|/begin_hook> attribute, if it exists, is |
1784
|
|
|
|
|
|
|
called, passing the object as the only argument. |
1785
|
|
|
|
|
|
|
|
1786
|
|
|
|
|
|
|
=item B<4 - Locate the Handler> |
1787
|
|
|
|
|
|
|
|
1788
|
|
|
|
|
|
|
Locating the Handler is a complex process; see |
1789
|
|
|
|
|
|
|
L<HANDLER SEARCH|/HANDLER-SEARCH:>. Briefly, the default behavior is to use |
1790
|
|
|
|
|
|
|
the first subroutine it finds from the following list of templates. The |
1791
|
|
|
|
|
|
|
list is evaluated once for each package in the |
1792
|
|
|
|
|
|
|
L<handler_pkgs|/handler_pkgs> attribute. |
1793
|
|
|
|
|
|
|
|
1794
|
|
|
|
|
|
|
<package>::_cp_<handler_name> |
1795
|
|
|
|
|
|
|
<package>::_<handler_name> |
1796
|
|
|
|
|
|
|
<package>::<handler_name> |
1797
|
|
|
|
|
|
|
|
1798
|
|
|
|
|
|
|
=item B<5 - Call Handler> |
1799
|
|
|
|
|
|
|
|
1800
|
|
|
|
|
|
|
The Handler is called with the object as the first argument. Any |
1801
|
|
|
|
|
|
|
arguments passed to the Proxy, beyond the handler-name, are propagated as |
1802
|
|
|
|
|
|
|
additional arguments to the Handler. |
1803
|
|
|
|
|
|
|
|
1804
|
|
|
|
|
|
|
=item B<6 - Add Calling Context (Stacktrace)> |
1805
|
|
|
|
|
|
|
|
1806
|
|
|
|
|
|
|
The method L<add_context()|/add_context> is invoked to generate a |
1807
|
|
|
|
|
|
|
Section with stacktrace content, as dictated by the |
1808
|
|
|
|
|
|
|
L<context|/context> attribute. |
1809
|
|
|
|
|
|
|
|
1810
|
|
|
|
|
|
|
=item B<7 - Call end_hook> |
1811
|
|
|
|
|
|
|
|
1812
|
|
|
|
|
|
|
The L<end_hook|/end_hook> attribute, if it exists, is called, |
1813
|
|
|
|
|
|
|
passing the object as the only argument. |
1814
|
|
|
|
|
|
|
|
1815
|
|
|
|
|
|
|
=item B<8 - Perform Disposition> |
1816
|
|
|
|
|
|
|
|
1817
|
|
|
|
|
|
|
The method L<perform_disposition()|/perform_disposition> is |
1818
|
|
|
|
|
|
|
invoked. Disposition is controlled by the |
1819
|
|
|
|
|
|
|
L<disposition|/disposition> attribute; typically this means |
1820
|
|
|
|
|
|
|
passing the B<Carp::Proxy> object to B<die()>. |
1821
|
|
|
|
|
|
|
|
1822
|
|
|
|
|
|
|
=back |
1823
|
|
|
|
|
|
|
|
1824
|
|
|
|
|
|
|
If L<perform_disposition()|/perform_disposition> returns, rather |
1825
|
|
|
|
|
|
|
than throwing, then the returned value is propagated as the return value |
1826
|
|
|
|
|
|
|
of the Proxy. |
1827
|
|
|
|
|
|
|
|
1828
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
1829
|
|
|
|
|
|
|
|
1830
|
|
|
|
|
|
|
All B<Carp::Proxy> object attributes have correspondingly named accessors. |
1831
|
|
|
|
|
|
|
When the accessors are invoked without arguments, they return the |
1832
|
|
|
|
|
|
|
attribute's value. Mutable (Read-Write) attributes have accessors that can |
1833
|
|
|
|
|
|
|
be supplied with an argument to set the attribute's value. |
1834
|
|
|
|
|
|
|
|
1835
|
|
|
|
|
|
|
Users generally do not create B<Carp::Proxy> objects directly; the Proxy |
1836
|
|
|
|
|
|
|
does that for them. The object constructor, L<new()|/new>, requires |
1837
|
|
|
|
|
|
|
specification for several of the attributes like |
1838
|
|
|
|
|
|
|
L<eval_error|/eval_error>. The Proxy supplies these required |
1839
|
|
|
|
|
|
|
attributes, but arguments to B<use()> or L<import()|/import> can override them. |
1840
|
|
|
|
|
|
|
|
1841
|
|
|
|
|
|
|
All other attributes invoke a "builder" method to initialize the |
1842
|
|
|
|
|
|
|
attribute value if one is not provided. Builder |
1843
|
|
|
|
|
|
|
methods are named with a prefix of B<'_build_'>. You can change default |
1844
|
|
|
|
|
|
|
values for these attributes with arguments to B<use()> / L<import()|/import>, |
1845
|
|
|
|
|
|
|
or by providing custom builder functions in a sub-class. |
1846
|
|
|
|
|
|
|
|
1847
|
|
|
|
|
|
|
=head2 arg |
1848
|
|
|
|
|
|
|
|
1849
|
|
|
|
|
|
|
I<arg> holds the value of Perl's B<$ARG ($_)>, as harvested from the |
1850
|
|
|
|
|
|
|
invoking environment. This can be handy if you are using |
1851
|
|
|
|
|
|
|
B<Try::Tiny>. |
1852
|
|
|
|
|
|
|
|
1853
|
|
|
|
|
|
|
=over 4 |
1854
|
|
|
|
|
|
|
|
1855
|
|
|
|
|
|
|
=item Builder: None; L<new()|/new> requires I<arg> specification. |
1856
|
|
|
|
|
|
|
|
1857
|
|
|
|
|
|
|
=item Default: N/A |
1858
|
|
|
|
|
|
|
|
1859
|
|
|
|
|
|
|
=item Domain: Any |
1860
|
|
|
|
|
|
|
|
1861
|
|
|
|
|
|
|
=item Affects: For user convenience; not used by B<Carp::Proxy> |
1862
|
|
|
|
|
|
|
|
1863
|
|
|
|
|
|
|
=item Mutability: Read-Only |
1864
|
|
|
|
|
|
|
|
1865
|
|
|
|
|
|
|
=back |
1866
|
|
|
|
|
|
|
|
1867
|
|
|
|
|
|
|
=head2 as_yaml |
1868
|
|
|
|
|
|
|
|
1869
|
|
|
|
|
|
|
The I<as_yaml> attribute is a flag that controls message rendering. |
1870
|
|
|
|
|
|
|
When False, message text is derived from the |
1871
|
|
|
|
|
|
|
L<sections|/sections> attribute; this is the normal mode of |
1872
|
|
|
|
|
|
|
operation. |
1873
|
|
|
|
|
|
|
|
1874
|
|
|
|
|
|
|
When I<as_yaml> is True message text is a B<YAML::Dump()> of the |
1875
|
|
|
|
|
|
|
B<Carp::Proxy> object. Serialization via YAML makes it possible to |
1876
|
|
|
|
|
|
|
propagate exceptions up from child processes. |
1877
|
|
|
|
|
|
|
|
1878
|
|
|
|
|
|
|
=over 4 |
1879
|
|
|
|
|
|
|
|
1880
|
|
|
|
|
|
|
=item Builder: _build_as_yaml() |
1881
|
|
|
|
|
|
|
|
1882
|
|
|
|
|
|
|
=item Default: 0 (False) |
1883
|
|
|
|
|
|
|
|
1884
|
|
|
|
|
|
|
=item Domain: Boolean |
1885
|
|
|
|
|
|
|
|
1886
|
|
|
|
|
|
|
=item Affects: L<render_message()|/render_message> |
1887
|
|
|
|
|
|
|
|
1888
|
|
|
|
|
|
|
=item Mutability: Read-Write |
1889
|
|
|
|
|
|
|
|
1890
|
|
|
|
|
|
|
=back |
1891
|
|
|
|
|
|
|
|
1892
|
|
|
|
|
|
|
=head2 banner_title |
1893
|
|
|
|
|
|
|
|
1894
|
|
|
|
|
|
|
The Banner is the first part of the message; I<banner_title> contains the |
1895
|
|
|
|
|
|
|
first word(s) in the Banner. |
1896
|
|
|
|
|
|
|
|
1897
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1898
|
|
|
|
|
|
|
Fatal << handler name >> |
1899
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1900
|
|
|
|
|
|
|
----- |
1901
|
|
|
|
|
|
|
\ |
1902
|
|
|
|
|
|
|
+------ banner_title |
1903
|
|
|
|
|
|
|
|
1904
|
|
|
|
|
|
|
=over 4 |
1905
|
|
|
|
|
|
|
|
1906
|
|
|
|
|
|
|
=item Builder: _build_banner_title() |
1907
|
|
|
|
|
|
|
|
1908
|
|
|
|
|
|
|
=item Default: 'Fatal' |
1909
|
|
|
|
|
|
|
|
1910
|
|
|
|
|
|
|
=item Domain: String |
1911
|
|
|
|
|
|
|
|
1912
|
|
|
|
|
|
|
=item Affects: L<banner()|/banner> |
1913
|
|
|
|
|
|
|
|
1914
|
|
|
|
|
|
|
=item Mutability: Read-Write |
1915
|
|
|
|
|
|
|
|
1916
|
|
|
|
|
|
|
=back |
1917
|
|
|
|
|
|
|
|
1918
|
|
|
|
|
|
|
=head2 begin_hook |
1919
|
|
|
|
|
|
|
|
1920
|
|
|
|
|
|
|
If I<begin_hook> contains a CodeRef then the Proxy will call the CodeRef |
1921
|
|
|
|
|
|
|
immediately after constructing the B<Carp::Proxy> object. The object |
1922
|
|
|
|
|
|
|
is passed as the only argument. |
1923
|
|
|
|
|
|
|
|
1924
|
|
|
|
|
|
|
A I<begin_hook> is a great way to always do some activity at the start of |
1925
|
|
|
|
|
|
|
every exception - before any Handler gets control. |
1926
|
|
|
|
|
|
|
|
1927
|
|
|
|
|
|
|
=over 4 |
1928
|
|
|
|
|
|
|
|
1929
|
|
|
|
|
|
|
=item Builder: _build_begin_hook() |
1930
|
|
|
|
|
|
|
|
1931
|
|
|
|
|
|
|
=item Default: undef |
1932
|
|
|
|
|
|
|
|
1933
|
|
|
|
|
|
|
=item Domain: undef or a CodeRef |
1934
|
|
|
|
|
|
|
|
1935
|
|
|
|
|
|
|
=item Affects: L<PROXY-INVOCATION|/PROXY-INVOCATION:> |
1936
|
|
|
|
|
|
|
|
1937
|
|
|
|
|
|
|
=item Mutability: Read-Write |
1938
|
|
|
|
|
|
|
|
1939
|
|
|
|
|
|
|
=back |
1940
|
|
|
|
|
|
|
|
1941
|
|
|
|
|
|
|
=head2 body_indent |
1942
|
|
|
|
|
|
|
|
1943
|
|
|
|
|
|
|
I<body_indent> influences the presentation of paragraphs created |
1944
|
|
|
|
|
|
|
by the Section creating methods L<filled()|/filled> and |
1945
|
|
|
|
|
|
|
L<fixed()|/fixed>. Use I<body_indent> to determine the amount of |
1946
|
|
|
|
|
|
|
additional indentation, beyond L<header_indent|/header_indent>, |
1947
|
|
|
|
|
|
|
that is applied to Section paragraphs. |
1948
|
|
|
|
|
|
|
|
1949
|
|
|
|
|
|
|
=over 4 |
1950
|
|
|
|
|
|
|
|
1951
|
|
|
|
|
|
|
=item Builder: _build_body_indent() |
1952
|
|
|
|
|
|
|
|
1953
|
|
|
|
|
|
|
=item Default: 2 |
1954
|
|
|
|
|
|
|
|
1955
|
|
|
|
|
|
|
=item Domain: Non-negative integers |
1956
|
|
|
|
|
|
|
|
1957
|
|
|
|
|
|
|
=item Affects: L<filled_section()|/filled_section> and L<fixed_section()|/fixed_section> |
1958
|
|
|
|
|
|
|
|
1959
|
|
|
|
|
|
|
=item Mutability: Read-Write |
1960
|
|
|
|
|
|
|
|
1961
|
|
|
|
|
|
|
=back |
1962
|
|
|
|
|
|
|
|
1963
|
|
|
|
|
|
|
=head2 child_error |
1964
|
|
|
|
|
|
|
|
1965
|
|
|
|
|
|
|
I<child_error> holds the value of Perl's B<$CHILD_ERROR ($?)>, as harvested |
1966
|
|
|
|
|
|
|
from the invoking environment. |
1967
|
|
|
|
|
|
|
|
1968
|
|
|
|
|
|
|
=over 4 |
1969
|
|
|
|
|
|
|
|
1970
|
|
|
|
|
|
|
=item Builder: None; L<new()|/new> requires I<child_error> specification. |
1971
|
|
|
|
|
|
|
|
1972
|
|
|
|
|
|
|
=item Default: N/A |
1973
|
|
|
|
|
|
|
|
1974
|
|
|
|
|
|
|
=item Domain: Any |
1975
|
|
|
|
|
|
|
|
1976
|
|
|
|
|
|
|
=item Affects: L<decipher_child_error()|/decipher_child_error> |
1977
|
|
|
|
|
|
|
|
1978
|
|
|
|
|
|
|
=item Mutability: Read-Only |
1979
|
|
|
|
|
|
|
|
1980
|
|
|
|
|
|
|
=back |
1981
|
|
|
|
|
|
|
|
1982
|
|
|
|
|
|
|
=head2 columns |
1983
|
|
|
|
|
|
|
|
1984
|
|
|
|
|
|
|
The I<columns> attribute sets the line width target for the Banner and |
1985
|
|
|
|
|
|
|
for any filled Sections. Values below about 30 are not practical. |
1986
|
|
|
|
|
|
|
|
1987
|
|
|
|
|
|
|
=over 4 |
1988
|
|
|
|
|
|
|
|
1989
|
|
|
|
|
|
|
=item Builder: _build_columns() |
1990
|
|
|
|
|
|
|
|
1991
|
|
|
|
|
|
|
=item Default: 78 |
1992
|
|
|
|
|
|
|
|
1993
|
|
|
|
|
|
|
=item Domain: Positive Integers |
1994
|
|
|
|
|
|
|
|
1995
|
|
|
|
|
|
|
=item Affects: L<banner()|/banner> and L<filled_section()|/filled_section> |
1996
|
|
|
|
|
|
|
|
1997
|
|
|
|
|
|
|
=item Mutability: Read-Write |
1998
|
|
|
|
|
|
|
|
1999
|
|
|
|
|
|
|
=back |
2000
|
|
|
|
|
|
|
|
2001
|
|
|
|
|
|
|
=head2 context |
2002
|
|
|
|
|
|
|
|
2003
|
|
|
|
|
|
|
The I<context> attribute controls the generation of a stacktrace Section. |
2004
|
|
|
|
|
|
|
|
2005
|
|
|
|
|
|
|
=over 4 |
2006
|
|
|
|
|
|
|
|
2007
|
|
|
|
|
|
|
=item Builder: _build_context() |
2008
|
|
|
|
|
|
|
|
2009
|
|
|
|
|
|
|
=item Default: 'confess' |
2010
|
|
|
|
|
|
|
|
2011
|
|
|
|
|
|
|
=item Domain: |
2012
|
|
|
|
|
|
|
|
2013
|
|
|
|
|
|
|
=over 4 |
2014
|
|
|
|
|
|
|
|
2015
|
|
|
|
|
|
|
=item 'none' - No Section generated. |
2016
|
|
|
|
|
|
|
|
2017
|
|
|
|
|
|
|
=item 'die' - Describe where Proxy was called. |
2018
|
|
|
|
|
|
|
|
2019
|
|
|
|
|
|
|
=item 'croak' - Describe where Proxy's caller was called. |
2020
|
|
|
|
|
|
|
|
2021
|
|
|
|
|
|
|
=item 'confess' - Stacktrace, starting with Proxy call. |
2022
|
|
|
|
|
|
|
|
2023
|
|
|
|
|
|
|
=item 'internals' - Complete stacktrace with Carp::Proxy guts. |
2024
|
|
|
|
|
|
|
|
2025
|
|
|
|
|
|
|
=item CodeRef - Do it yourself. |
2026
|
|
|
|
|
|
|
|
2027
|
|
|
|
|
|
|
=back |
2028
|
|
|
|
|
|
|
|
2029
|
|
|
|
|
|
|
=item Affects: L<add_context()|/add_context> |
2030
|
|
|
|
|
|
|
|
2031
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2032
|
|
|
|
|
|
|
|
2033
|
|
|
|
|
|
|
=back |
2034
|
|
|
|
|
|
|
|
2035
|
|
|
|
|
|
|
=head2 disposition |
2036
|
|
|
|
|
|
|
|
2037
|
|
|
|
|
|
|
The I<disposition> attribute controls how the exception is thrown. |
2038
|
|
|
|
|
|
|
|
2039
|
|
|
|
|
|
|
=over 4 |
2040
|
|
|
|
|
|
|
|
2041
|
|
|
|
|
|
|
=item Builder: _build_disposition() |
2042
|
|
|
|
|
|
|
|
2043
|
|
|
|
|
|
|
=item Default: 'die' |
2044
|
|
|
|
|
|
|
|
2045
|
|
|
|
|
|
|
=item Domain: |
2046
|
|
|
|
|
|
|
|
2047
|
|
|
|
|
|
|
=over 4 |
2048
|
|
|
|
|
|
|
|
2049
|
|
|
|
|
|
|
=item 'return' - No exception thrown; Proxy returns. |
2050
|
|
|
|
|
|
|
|
2051
|
|
|
|
|
|
|
=item 'warn' - Carp::Proxy object passed to Perl's B<warn()>. |
2052
|
|
|
|
|
|
|
|
2053
|
|
|
|
|
|
|
=item 'die' - Carp::Proxy object passed to Perl's B<die()>. |
2054
|
|
|
|
|
|
|
|
2055
|
|
|
|
|
|
|
=item CodeRef - Do it yourself. |
2056
|
|
|
|
|
|
|
|
2057
|
|
|
|
|
|
|
=back |
2058
|
|
|
|
|
|
|
|
2059
|
|
|
|
|
|
|
=item Affects: L<perform_disposition()|/perform_disposition> |
2060
|
|
|
|
|
|
|
|
2061
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2062
|
|
|
|
|
|
|
|
2063
|
|
|
|
|
|
|
=back |
2064
|
|
|
|
|
|
|
|
2065
|
|
|
|
|
|
|
=head2 end_hook |
2066
|
|
|
|
|
|
|
|
2067
|
|
|
|
|
|
|
If I<end_hook> contains a CodeRef then the Proxy will call the CodeRef |
2068
|
|
|
|
|
|
|
just before performing disposition. The B<Carp::Proxy> object is |
2069
|
|
|
|
|
|
|
passed as the only argument. |
2070
|
|
|
|
|
|
|
|
2071
|
|
|
|
|
|
|
The I<end_hook> is handy for things that you want all Handlers to do as |
2072
|
|
|
|
|
|
|
their last action. An example might be writing to a logfile. |
2073
|
|
|
|
|
|
|
|
2074
|
|
|
|
|
|
|
=over 4 |
2075
|
|
|
|
|
|
|
|
2076
|
|
|
|
|
|
|
=item Builder: _build_end_hook() |
2077
|
|
|
|
|
|
|
|
2078
|
|
|
|
|
|
|
=item Default: undef |
2079
|
|
|
|
|
|
|
|
2080
|
|
|
|
|
|
|
=item Domain: undef or a CodeRef |
2081
|
|
|
|
|
|
|
|
2082
|
|
|
|
|
|
|
=item Affects: L<PROXY-INVOCATION|/PROXY-INVOCATION:> |
2083
|
|
|
|
|
|
|
|
2084
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2085
|
|
|
|
|
|
|
|
2086
|
|
|
|
|
|
|
=back |
2087
|
|
|
|
|
|
|
|
2088
|
|
|
|
|
|
|
=head2 eval_error |
2089
|
|
|
|
|
|
|
|
2090
|
|
|
|
|
|
|
The I<eval_error> attribute holds the value of Perl's B<$EVAL_ERROR ($@)>, |
2091
|
|
|
|
|
|
|
as harvested from the invoking environment. |
2092
|
|
|
|
|
|
|
|
2093
|
|
|
|
|
|
|
=over 4 |
2094
|
|
|
|
|
|
|
|
2095
|
|
|
|
|
|
|
=item Builder: None; L<new()|/new> requires an I<eval_error> specification |
2096
|
|
|
|
|
|
|
|
2097
|
|
|
|
|
|
|
=item Default: N/A |
2098
|
|
|
|
|
|
|
|
2099
|
|
|
|
|
|
|
=item Domain: Any |
2100
|
|
|
|
|
|
|
|
2101
|
|
|
|
|
|
|
=item Affects: For user convenience; not used by B<Carp::Proxy> |
2102
|
|
|
|
|
|
|
|
2103
|
|
|
|
|
|
|
=item Mutability: Read-Only |
2104
|
|
|
|
|
|
|
|
2105
|
|
|
|
|
|
|
=back |
2106
|
|
|
|
|
|
|
|
2107
|
|
|
|
|
|
|
=head2 exit_code |
2108
|
|
|
|
|
|
|
|
2109
|
|
|
|
|
|
|
I<exit_code> is used to set the value harvested by the operating system |
2110
|
|
|
|
|
|
|
when a process dies. |
2111
|
|
|
|
|
|
|
|
2112
|
|
|
|
|
|
|
=over 4 |
2113
|
|
|
|
|
|
|
|
2114
|
|
|
|
|
|
|
=item Builder: _build_exit_code() |
2115
|
|
|
|
|
|
|
|
2116
|
|
|
|
|
|
|
=item Default: 1 |
2117
|
|
|
|
|
|
|
|
2118
|
|
|
|
|
|
|
=item Domain: Integers greater than Zero |
2119
|
|
|
|
|
|
|
|
2120
|
|
|
|
|
|
|
=item Affects: L<perform_disposition()|/perform_disposition> |
2121
|
|
|
|
|
|
|
|
2122
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2123
|
|
|
|
|
|
|
|
2124
|
|
|
|
|
|
|
=back |
2125
|
|
|
|
|
|
|
|
2126
|
|
|
|
|
|
|
=head2 fq_proxy_name |
2127
|
|
|
|
|
|
|
|
2128
|
|
|
|
|
|
|
I<fq_proxy_name> is the fully-qualified proxy-name. This is the Proxy's |
2129
|
|
|
|
|
|
|
name, complete with exported package qualifier. This might be useful if |
2130
|
|
|
|
|
|
|
a Handler wants to know the parental Proxy. |
2131
|
|
|
|
|
|
|
|
2132
|
|
|
|
|
|
|
=over 4 |
2133
|
|
|
|
|
|
|
|
2134
|
|
|
|
|
|
|
=item Builder: None; L<new()|/new> requires I<fq_proxy_name> specification |
2135
|
|
|
|
|
|
|
|
2136
|
|
|
|
|
|
|
=item Default: N/A |
2137
|
|
|
|
|
|
|
|
2138
|
|
|
|
|
|
|
=item Domain: String |
2139
|
|
|
|
|
|
|
|
2140
|
|
|
|
|
|
|
=item Affects: L<add_context()|/add_context> |
2141
|
|
|
|
|
|
|
|
2142
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2143
|
|
|
|
|
|
|
|
2144
|
|
|
|
|
|
|
=back |
2145
|
|
|
|
|
|
|
|
2146
|
|
|
|
|
|
|
=head2 handler_name |
2147
|
|
|
|
|
|
|
|
2148
|
|
|
|
|
|
|
The Proxy saves its first argument, the Handler, in I<handler_name>. |
2149
|
|
|
|
|
|
|
|
2150
|
|
|
|
|
|
|
=over 4 |
2151
|
|
|
|
|
|
|
|
2152
|
|
|
|
|
|
|
=item Builder: None; L<new()|/new> requires I<handler_name> specification |
2153
|
|
|
|
|
|
|
|
2154
|
|
|
|
|
|
|
=item Default: N/A |
2155
|
|
|
|
|
|
|
|
2156
|
|
|
|
|
|
|
=item Domain: String |
2157
|
|
|
|
|
|
|
|
2158
|
|
|
|
|
|
|
=item Affects: L<banner()|/banner>, L<HANDLER SEARCH|/HANDLER-SEARCH:> |
2159
|
|
|
|
|
|
|
|
2160
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2161
|
|
|
|
|
|
|
|
2162
|
|
|
|
|
|
|
=back |
2163
|
|
|
|
|
|
|
|
2164
|
|
|
|
|
|
|
=head2 handler_pkgs |
2165
|
|
|
|
|
|
|
|
2166
|
|
|
|
|
|
|
The search for a Handler subroutine is performed in each of the packages |
2167
|
|
|
|
|
|
|
in the ArrayRef I<handler_pkgs>. A copy of |
2168
|
|
|
|
|
|
|
L<proxy_package|/proxy_package> is automatically appended, by |
2169
|
|
|
|
|
|
|
the Proxy after object construction. |
2170
|
|
|
|
|
|
|
|
2171
|
|
|
|
|
|
|
=over 4 |
2172
|
|
|
|
|
|
|
|
2173
|
|
|
|
|
|
|
=item Builder: _build_handler_pkgs() |
2174
|
|
|
|
|
|
|
|
2175
|
|
|
|
|
|
|
=item Default: [] |
2176
|
|
|
|
|
|
|
|
2177
|
|
|
|
|
|
|
=item Domain: ArrayRef |
2178
|
|
|
|
|
|
|
|
2179
|
|
|
|
|
|
|
=item Affects: L<HANDLER SEARCH|/HANDLER-SEARCH:> |
2180
|
|
|
|
|
|
|
|
2181
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2182
|
|
|
|
|
|
|
|
2183
|
|
|
|
|
|
|
=back |
2184
|
|
|
|
|
|
|
|
2185
|
|
|
|
|
|
|
=head2 handler_prefix |
2186
|
|
|
|
|
|
|
|
2187
|
|
|
|
|
|
|
I<handler_prefix> affects how the search for a Handler is performed. |
2188
|
|
|
|
|
|
|
The list of templates that are tried during L<HANDLER SEARCH|/HANDLER-SEARCH:> |
2189
|
|
|
|
|
|
|
is based on I<handler_prefix>. |
2190
|
|
|
|
|
|
|
|
2191
|
|
|
|
|
|
|
=over 4 |
2192
|
|
|
|
|
|
|
|
2193
|
|
|
|
|
|
|
=item Builder: _build_handler_prefix() |
2194
|
|
|
|
|
|
|
|
2195
|
|
|
|
|
|
|
=item Default: undef |
2196
|
|
|
|
|
|
|
|
2197
|
|
|
|
|
|
|
=item Domain: undef or String |
2198
|
|
|
|
|
|
|
|
2199
|
|
|
|
|
|
|
=item Affects: L<HANDLER SEARCH|/HANDLER-SEARCH:> |
2200
|
|
|
|
|
|
|
|
2201
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2202
|
|
|
|
|
|
|
|
2203
|
|
|
|
|
|
|
=back |
2204
|
|
|
|
|
|
|
|
2205
|
|
|
|
|
|
|
=head2 header_indent |
2206
|
|
|
|
|
|
|
|
2207
|
|
|
|
|
|
|
Section Headers are indented from the left margin by I<header_indent> |
2208
|
|
|
|
|
|
|
spaces. |
2209
|
|
|
|
|
|
|
|
2210
|
|
|
|
|
|
|
=over 4 |
2211
|
|
|
|
|
|
|
|
2212
|
|
|
|
|
|
|
=item Builder: _build_header_indent() |
2213
|
|
|
|
|
|
|
|
2214
|
|
|
|
|
|
|
=item Default: 2 |
2215
|
|
|
|
|
|
|
|
2216
|
|
|
|
|
|
|
=item Domain: Non-negative Integers |
2217
|
|
|
|
|
|
|
|
2218
|
|
|
|
|
|
|
=item Affects: L<header()|/header>, L<filled_section()|/filled_section> L<fixed_section()|/fixed_section> |
2219
|
|
|
|
|
|
|
|
2220
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2221
|
|
|
|
|
|
|
|
2222
|
|
|
|
|
|
|
=back |
2223
|
|
|
|
|
|
|
|
2224
|
|
|
|
|
|
|
=head2 maintainer |
2225
|
|
|
|
|
|
|
|
2226
|
|
|
|
|
|
|
The L<contact_maintainer()|/contact_maintainer> method produces a |
2227
|
|
|
|
|
|
|
Section that urges the message recipient to contact the maintainer. The |
2228
|
|
|
|
|
|
|
Section is created only if the I<maintainer> attribute is non-empty. A |
2229
|
|
|
|
|
|
|
string containing an email address and a telephone number works well. |
2230
|
|
|
|
|
|
|
|
2231
|
|
|
|
|
|
|
=over 4 |
2232
|
|
|
|
|
|
|
|
2233
|
|
|
|
|
|
|
=item Builder: _build_maintainer() |
2234
|
|
|
|
|
|
|
|
2235
|
|
|
|
|
|
|
=item Default: '' |
2236
|
|
|
|
|
|
|
|
2237
|
|
|
|
|
|
|
=item Domain: String |
2238
|
|
|
|
|
|
|
|
2239
|
|
|
|
|
|
|
=item Affects: L<contact_maintainer()|/contact_maintainer> |
2240
|
|
|
|
|
|
|
|
2241
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2242
|
|
|
|
|
|
|
|
2243
|
|
|
|
|
|
|
=back |
2244
|
|
|
|
|
|
|
|
2245
|
|
|
|
|
|
|
=head2 numeric_errno |
2246
|
|
|
|
|
|
|
|
2247
|
|
|
|
|
|
|
The I<numeric_errno> attribute contains the value of |
2248
|
|
|
|
|
|
|
Perl's B<$ERRNO ($!)>, as harvested from the invoking environment. The |
2249
|
|
|
|
|
|
|
value is obtained by evaluating B<$ERRNO> in a numeric context. |
2250
|
|
|
|
|
|
|
|
2251
|
|
|
|
|
|
|
=over 4 |
2252
|
|
|
|
|
|
|
|
2253
|
|
|
|
|
|
|
=item Builder: None; L<new()|/new> requires I<numeric_errno> specification |
2254
|
|
|
|
|
|
|
|
2255
|
|
|
|
|
|
|
=item Default: N/A |
2256
|
|
|
|
|
|
|
|
2257
|
|
|
|
|
|
|
=item Domain: Any |
2258
|
|
|
|
|
|
|
|
2259
|
|
|
|
|
|
|
=item Affects: For user convenience; not used by B<Carp::Proxy> |
2260
|
|
|
|
|
|
|
|
2261
|
|
|
|
|
|
|
=item Mutability: Read-Only |
2262
|
|
|
|
|
|
|
|
2263
|
|
|
|
|
|
|
=back |
2264
|
|
|
|
|
|
|
|
2265
|
|
|
|
|
|
|
=head2 pod_filename |
2266
|
|
|
|
|
|
|
|
2267
|
|
|
|
|
|
|
The L<synopsis()|/synopsis> method searches for POD in |
2268
|
|
|
|
|
|
|
I<pod_filename>. |
2269
|
|
|
|
|
|
|
|
2270
|
|
|
|
|
|
|
=over 4 |
2271
|
|
|
|
|
|
|
|
2272
|
|
|
|
|
|
|
=item Builder: _build_pod_filename() |
2273
|
|
|
|
|
|
|
|
2274
|
|
|
|
|
|
|
=item Default: L<proxy_filename|/proxy_filename>. |
2275
|
|
|
|
|
|
|
|
2276
|
|
|
|
|
|
|
=item Domain: String |
2277
|
|
|
|
|
|
|
|
2278
|
|
|
|
|
|
|
=item Affects: L<synopsis()|/synopsis> |
2279
|
|
|
|
|
|
|
|
2280
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2281
|
|
|
|
|
|
|
|
2282
|
|
|
|
|
|
|
=back |
2283
|
|
|
|
|
|
|
|
2284
|
|
|
|
|
|
|
=head2 proxy_filename |
2285
|
|
|
|
|
|
|
|
2286
|
|
|
|
|
|
|
The filename containing the code that requested construction of the Proxy, |
2287
|
|
|
|
|
|
|
either by B<use()> or L<import()|/import>. |
2288
|
|
|
|
|
|
|
|
2289
|
|
|
|
|
|
|
=over 4 |
2290
|
|
|
|
|
|
|
|
2291
|
|
|
|
|
|
|
=item Builder: None; L<new()|/new> requires I<proxy_filename> specification |
2292
|
|
|
|
|
|
|
|
2293
|
|
|
|
|
|
|
=item Default: N/A |
2294
|
|
|
|
|
|
|
|
2295
|
|
|
|
|
|
|
=item Domain: String |
2296
|
|
|
|
|
|
|
|
2297
|
|
|
|
|
|
|
=item Affects: L<pod_filename|/pod_filename>. |
2298
|
|
|
|
|
|
|
|
2299
|
|
|
|
|
|
|
=item Mutability: Read-Only |
2300
|
|
|
|
|
|
|
|
2301
|
|
|
|
|
|
|
=back |
2302
|
|
|
|
|
|
|
|
2303
|
|
|
|
|
|
|
=head2 proxy_name |
2304
|
|
|
|
|
|
|
|
2305
|
|
|
|
|
|
|
I<proxy_name> contains the name of the Proxy subroutine. |
2306
|
|
|
|
|
|
|
|
2307
|
|
|
|
|
|
|
The default I<proxy_name> is B<'fatal'>. |
2308
|
|
|
|
|
|
|
|
2309
|
|
|
|
|
|
|
The only time this attribute is used is when B<use()> or L<import()|/import> |
2310
|
|
|
|
|
|
|
are called without arguments. Defining a B<_build_proxy_name()> in |
2311
|
|
|
|
|
|
|
a sub class allows you to change the default name. |
2312
|
|
|
|
|
|
|
|
2313
|
|
|
|
|
|
|
=over 4 |
2314
|
|
|
|
|
|
|
|
2315
|
|
|
|
|
|
|
=item Builder: _build_proxy_name(); L<new()|/new> requires I<proxy_name> |
2316
|
|
|
|
|
|
|
|
2317
|
|
|
|
|
|
|
=item Default: 'fatal' |
2318
|
|
|
|
|
|
|
|
2319
|
|
|
|
|
|
|
=item Domain: String |
2320
|
|
|
|
|
|
|
|
2321
|
|
|
|
|
|
|
=item Affects: B<use()>, L<import()|/import> |
2322
|
|
|
|
|
|
|
|
2323
|
|
|
|
|
|
|
=item Mutability: Read-Only |
2324
|
|
|
|
|
|
|
|
2325
|
|
|
|
|
|
|
=back |
2326
|
|
|
|
|
|
|
|
2327
|
|
|
|
|
|
|
=head2 proxy_package |
2328
|
|
|
|
|
|
|
|
2329
|
|
|
|
|
|
|
The I<proxy_package> attribute is derived from the package that requested |
2330
|
|
|
|
|
|
|
construction of the Proxy, either by calling B<use()> or L<import()|/import>. |
2331
|
|
|
|
|
|
|
|
2332
|
|
|
|
|
|
|
=over 4 |
2333
|
|
|
|
|
|
|
|
2334
|
|
|
|
|
|
|
=item Builder: None; L<new()|/new> requires I<proxy_package> specification |
2335
|
|
|
|
|
|
|
|
2336
|
|
|
|
|
|
|
=item Default: Package of whatever subroutine called B<use()> or L<import()|/import> |
2337
|
|
|
|
|
|
|
|
2338
|
|
|
|
|
|
|
=item Domain: String |
2339
|
|
|
|
|
|
|
|
2340
|
|
|
|
|
|
|
=item Affects: L<handler_pkgs|/handler_pkgs> |
2341
|
|
|
|
|
|
|
|
2342
|
|
|
|
|
|
|
=item Mutability: Read-Only |
2343
|
|
|
|
|
|
|
|
2344
|
|
|
|
|
|
|
=back |
2345
|
|
|
|
|
|
|
|
2346
|
|
|
|
|
|
|
=head2 section_title |
2347
|
|
|
|
|
|
|
|
2348
|
|
|
|
|
|
|
The Section-creating methods L<filled()|/filled> and |
2349
|
|
|
|
|
|
|
L<fixed()|/fixed>, accept an optional, second argument to be used |
2350
|
|
|
|
|
|
|
as the title for the Section. When this optional argument is not |
2351
|
|
|
|
|
|
|
supplied, I<section_title> is used instead. |
2352
|
|
|
|
|
|
|
|
2353
|
|
|
|
|
|
|
=over 4 |
2354
|
|
|
|
|
|
|
|
2355
|
|
|
|
|
|
|
=item Builder: _build_section_title() |
2356
|
|
|
|
|
|
|
|
2357
|
|
|
|
|
|
|
=item Default: 'Description' |
2358
|
|
|
|
|
|
|
|
2359
|
|
|
|
|
|
|
=item Domain: Non-empty String |
2360
|
|
|
|
|
|
|
|
2361
|
|
|
|
|
|
|
=item Affects: L<header()|/header>, L<filled()|/filled>, L<fixed()|/fixed> |
2362
|
|
|
|
|
|
|
|
2363
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2364
|
|
|
|
|
|
|
|
2365
|
|
|
|
|
|
|
=back |
2366
|
|
|
|
|
|
|
|
2367
|
|
|
|
|
|
|
=head2 sections |
2368
|
|
|
|
|
|
|
|
2369
|
|
|
|
|
|
|
The Section-creating methods L<filled()|/filled>, |
2370
|
|
|
|
|
|
|
L<fixed()|/fixed> and L<raw()|/raw> create Section |
2371
|
|
|
|
|
|
|
specifications. Section specifications accumulate in the ArrayRef |
2372
|
|
|
|
|
|
|
I<sections>. |
2373
|
|
|
|
|
|
|
|
2374
|
|
|
|
|
|
|
=over 4 |
2375
|
|
|
|
|
|
|
|
2376
|
|
|
|
|
|
|
=item Builder: _build_sections() |
2377
|
|
|
|
|
|
|
|
2378
|
|
|
|
|
|
|
=item Default: [] |
2379
|
|
|
|
|
|
|
|
2380
|
|
|
|
|
|
|
=item Domain: ArrayRef of section-specifications |
2381
|
|
|
|
|
|
|
|
2382
|
|
|
|
|
|
|
=item Affects: L<render_message()|/render_message> |
2383
|
|
|
|
|
|
|
|
2384
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2385
|
|
|
|
|
|
|
|
2386
|
|
|
|
|
|
|
=back |
2387
|
|
|
|
|
|
|
|
2388
|
|
|
|
|
|
|
=head2 string_errno |
2389
|
|
|
|
|
|
|
|
2390
|
|
|
|
|
|
|
I<string_errno> is a read-only attribute that contains the value of Perl's |
2391
|
|
|
|
|
|
|
B<$ERRNO ($!)>, harvested from the invoking environment. The value is |
2392
|
|
|
|
|
|
|
obtained by evaluating B<$ERRNO> in a string context. |
2393
|
|
|
|
|
|
|
|
2394
|
|
|
|
|
|
|
=over 4 |
2395
|
|
|
|
|
|
|
|
2396
|
|
|
|
|
|
|
=item Builder: None; L<new()|/new> requires I<string_errno> specification |
2397
|
|
|
|
|
|
|
|
2398
|
|
|
|
|
|
|
=item Default: N/A |
2399
|
|
|
|
|
|
|
|
2400
|
|
|
|
|
|
|
=item Domain: String |
2401
|
|
|
|
|
|
|
|
2402
|
|
|
|
|
|
|
=item Affects: L<errno_section()|/errno_section> |
2403
|
|
|
|
|
|
|
|
2404
|
|
|
|
|
|
|
=item Mutability: Read-Only |
2405
|
|
|
|
|
|
|
|
2406
|
|
|
|
|
|
|
=back |
2407
|
|
|
|
|
|
|
|
2408
|
|
|
|
|
|
|
=head2 tags |
2409
|
|
|
|
|
|
|
|
2410
|
|
|
|
|
|
|
Passing arbitrary data to the catching environment can sometimes be |
2411
|
|
|
|
|
|
|
useful. The I<tags> attribute is a HashRef for tag-value pairs of user |
2412
|
|
|
|
|
|
|
data. The attribute is completely ignored by the Proxy and by |
2413
|
|
|
|
|
|
|
B<Carp::Proxy> methods. |
2414
|
|
|
|
|
|
|
|
2415
|
|
|
|
|
|
|
=over 4 |
2416
|
|
|
|
|
|
|
|
2417
|
|
|
|
|
|
|
=item Builder: _build_tags() |
2418
|
|
|
|
|
|
|
|
2419
|
|
|
|
|
|
|
=item Default: {} |
2420
|
|
|
|
|
|
|
|
2421
|
|
|
|
|
|
|
=item Domain: HashRef |
2422
|
|
|
|
|
|
|
|
2423
|
|
|
|
|
|
|
=item Affects: For user convenience; not used by B<Carp::Proxy> |
2424
|
|
|
|
|
|
|
|
2425
|
|
|
|
|
|
|
=item Mutability: Read-Write |
2426
|
|
|
|
|
|
|
|
2427
|
|
|
|
|
|
|
=back |
2428
|
|
|
|
|
|
|
|
2429
|
|
|
|
|
|
|
=head1 METHODS |
2430
|
|
|
|
|
|
|
|
2431
|
|
|
|
|
|
|
The documentation for each method starts off with a 'Usage' description. |
2432
|
|
|
|
|
|
|
A description will look something like this: |
2433
|
|
|
|
|
|
|
|
2434
|
|
|
|
|
|
|
Usage: |
2435
|
|
|
|
|
|
|
<void> $cp->append_handler_package( $pkg <, $pkg2 ...>); |
2436
|
|
|
|
|
|
|
|
2437
|
|
|
|
|
|
|
The word enclosed in angle-brackets, at the beginning, (Like |
2438
|
|
|
|
|
|
|
B<E<lt>voidE<gt>>) attempts to convey the return value. Arguments in |
2439
|
|
|
|
|
|
|
angle-brackets are optional, with the ellipsis (B<...>) implying |
2440
|
|
|
|
|
|
|
repeatability. B<$cp> is a B<Carp::Proxy> object. B<$class>, if used as |
2441
|
|
|
|
|
|
|
the invoker, indicates a class method. |
2442
|
|
|
|
|
|
|
|
2443
|
|
|
|
|
|
|
=head2 add_context |
2444
|
|
|
|
|
|
|
|
2445
|
|
|
|
|
|
|
Usage: |
2446
|
|
|
|
|
|
|
<void> $cp->add_context(); |
2447
|
|
|
|
|
|
|
|
2448
|
|
|
|
|
|
|
B<add_context()> creates a Section that contains a stacktrace of where the |
2449
|
|
|
|
|
|
|
Proxy was invoked. The L<context|/context> attribute controls |
2450
|
|
|
|
|
|
|
whether or not the Section is generated, as well as what kind of |
2451
|
|
|
|
|
|
|
stacktrace is produced. |
2452
|
|
|
|
|
|
|
|
2453
|
|
|
|
|
|
|
B<add_context()> is called by the Proxy when the Handler returns. |
2454
|
|
|
|
|
|
|
|
2455
|
|
|
|
|
|
|
Perl's B<caller()> is used to probe the callstack and report stackframes. |
2456
|
|
|
|
|
|
|
Stackframes are rendered on one line if the length would not exceed the |
2457
|
|
|
|
|
|
|
value of the L<columns|/columns> attribute. Long lines are |
2458
|
|
|
|
|
|
|
folded at the filename portion of the stackframe and given |
2459
|
|
|
|
|
|
|
L<body_indent|/body_indent> extra spaces of indentation. |
2460
|
|
|
|
|
|
|
|
2461
|
|
|
|
|
|
|
The L<context|/context> attribute may take on any of these |
2462
|
|
|
|
|
|
|
values: |
2463
|
|
|
|
|
|
|
|
2464
|
|
|
|
|
|
|
=over 4 |
2465
|
|
|
|
|
|
|
|
2466
|
|
|
|
|
|
|
=item B<'none'> |
2467
|
|
|
|
|
|
|
|
2468
|
|
|
|
|
|
|
The I<context> of C<'none'> is a request to forego stacktrace generation. |
2469
|
|
|
|
|
|
|
No Section is produced. |
2470
|
|
|
|
|
|
|
|
2471
|
|
|
|
|
|
|
=item B<'die'> |
2472
|
|
|
|
|
|
|
|
2473
|
|
|
|
|
|
|
The I<context> of C<'die'> adds a Section containing a single entry. The |
2474
|
|
|
|
|
|
|
entry details the source location where the Proxy was invoked. The effect |
2475
|
|
|
|
|
|
|
is intended to mimic Perl's behavior when B<die()> is passed a string |
2476
|
|
|
|
|
|
|
WITHOUT a trailing newline. |
2477
|
|
|
|
|
|
|
|
2478
|
|
|
|
|
|
|
The title for the Section is C<'Exception'>. |
2479
|
|
|
|
|
|
|
|
2480
|
|
|
|
|
|
|
*** Exception *** |
2481
|
|
|
|
|
|
|
fatal called from line 27 of /home/duane/bin/assim |
2482
|
|
|
|
|
|
|
|
2483
|
|
|
|
|
|
|
=item B<'croak'> |
2484
|
|
|
|
|
|
|
|
2485
|
|
|
|
|
|
|
The I<context> of C<'croak'> adds a Section that identifies the subroutine |
2486
|
|
|
|
|
|
|
that invoked the Proxy. The effect is intended to mimic the behavior of |
2487
|
|
|
|
|
|
|
B<Carp::croak()>, which assigns blame to the caller. |
2488
|
|
|
|
|
|
|
|
2489
|
|
|
|
|
|
|
The title for the Section is C<'Exception'>. |
2490
|
|
|
|
|
|
|
|
2491
|
|
|
|
|
|
|
*** Exception *** |
2492
|
|
|
|
|
|
|
perform_query called from line 1172 of |
2493
|
|
|
|
|
|
|
/opt/barkta/linux/v3.7/bin/ReadRecords |
2494
|
|
|
|
|
|
|
|
2495
|
|
|
|
|
|
|
=item B<'confess'> |
2496
|
|
|
|
|
|
|
|
2497
|
|
|
|
|
|
|
The I<context> setting of C<'confess'> creates a multi-line Section. |
2498
|
|
|
|
|
|
|
Lines in the Section correspond to stackframes from nearest to outermost, |
2499
|
|
|
|
|
|
|
much like the behavior of B<Carp::confess>. |
2500
|
|
|
|
|
|
|
|
2501
|
|
|
|
|
|
|
C<'confess'> is the default I<context> for B<Carp::Proxy> objects. |
2502
|
|
|
|
|
|
|
|
2503
|
|
|
|
|
|
|
The Section title is 'Stacktrace'. |
2504
|
|
|
|
|
|
|
|
2505
|
|
|
|
|
|
|
=item B<'internals'> |
2506
|
|
|
|
|
|
|
|
2507
|
|
|
|
|
|
|
The I<context> setting C<'internals'> is very similar to the setting |
2508
|
|
|
|
|
|
|
C<'confess'>. Both produce full stacktraces, but C<'confess'> omits |
2509
|
|
|
|
|
|
|
stackframes that originate on behalf of the Proxy. You normally do |
2510
|
|
|
|
|
|
|
not want to see B<Carp::Proxy> stackframes, although they might be helpful |
2511
|
|
|
|
|
|
|
in debugging a sub-class. C<'internals'> gives you everything. |
2512
|
|
|
|
|
|
|
|
2513
|
|
|
|
|
|
|
The Section title is 'Stacktrace'. |
2514
|
|
|
|
|
|
|
|
2515
|
|
|
|
|
|
|
=item B<CodeRef> |
2516
|
|
|
|
|
|
|
|
2517
|
|
|
|
|
|
|
By providing a CodeRef users can completely control context reporting. |
2518
|
|
|
|
|
|
|
|
2519
|
|
|
|
|
|
|
The Proxy will make a callback to I<CodeRef> immediately after the Handler |
2520
|
|
|
|
|
|
|
returns. The B<Carp::Proxy> object will be passed as the only argument. |
2521
|
|
|
|
|
|
|
The CodeRef should create a Section using the L<filled()|/filled>, |
2522
|
|
|
|
|
|
|
L<fixed()|/fixed> or L<raw()|/raw> methods. |
2523
|
|
|
|
|
|
|
|
2524
|
|
|
|
|
|
|
The B<Carp> module from the Perl standard library provides some complex |
2525
|
|
|
|
|
|
|
functionality for ignoring stackframes that you may find useful. |
2526
|
|
|
|
|
|
|
|
2527
|
|
|
|
|
|
|
=back |
2528
|
|
|
|
|
|
|
|
2529
|
|
|
|
|
|
|
=head2 append_handler_package |
2530
|
|
|
|
|
|
|
|
2531
|
|
|
|
|
|
|
Usage: |
2532
|
|
|
|
|
|
|
<void> $cp->append_handler_package( $pkg <, $pkg2 ...>); |
2533
|
|
|
|
|
|
|
|
2534
|
|
|
|
|
|
|
The attribute L<handler_pkgs|/handler_pkgs> is an ArrayRef. |
2535
|
|
|
|
|
|
|
B<append_handler_package()> is sugar to make adding packages to the end of |
2536
|
|
|
|
|
|
|
L<handler_pkgs|/handler_pkgs> easier. |
2537
|
|
|
|
|
|
|
|
2538
|
|
|
|
|
|
|
=head2 append_section |
2539
|
|
|
|
|
|
|
|
2540
|
|
|
|
|
|
|
Usage: |
2541
|
|
|
|
|
|
|
<void> $cp->append_section( $array_ref <, $array_ref2...>); |
2542
|
|
|
|
|
|
|
|
2543
|
|
|
|
|
|
|
The L<sections|/sections> attribute is an ArrayRef containing |
2544
|
|
|
|
|
|
|
child ArrayRefs, one for each Section (like filled(), fixed() etc.). |
2545
|
|
|
|
|
|
|
B<append_section()> is sugar to make adding a Section request to the |
2546
|
|
|
|
|
|
|
L<sections|/sections> attribute, easier. Section requests are |
2547
|
|
|
|
|
|
|
added to the end of L<sections|/sections> (appended). |
2548
|
|
|
|
|
|
|
|
2549
|
|
|
|
|
|
|
=head2 banner |
2550
|
|
|
|
|
|
|
|
2551
|
|
|
|
|
|
|
Usage: |
2552
|
|
|
|
|
|
|
<String> $cp->banner(); |
2553
|
|
|
|
|
|
|
|
2554
|
|
|
|
|
|
|
B<banner()> produces the multi-line introduction to a diagnostic message. |
2555
|
|
|
|
|
|
|
The Banner is intended to stand out visually so it fills up the horizontal |
2556
|
|
|
|
|
|
|
space from left to right margins. The value of |
2557
|
|
|
|
|
|
|
L<columns|/columns> dictates the amount of fill needed. The |
2558
|
|
|
|
|
|
|
Banner looks something like this: |
2559
|
|
|
|
|
|
|
|
2560
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2561
|
|
|
|
|
|
|
<banner_title> << <cleansed_handler> >> |
2562
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2563
|
|
|
|
|
|
|
|
2564
|
|
|
|
|
|
|
In the above template, I<banner_title> is taken directly from the |
2565
|
|
|
|
|
|
|
L<banner_title|/banner_title> attribute. I<cleansed_handler> is |
2566
|
|
|
|
|
|
|
generated by invoking |
2567
|
|
|
|
|
|
|
L<identifier_presentation()|/identifier_presentation> on the |
2568
|
|
|
|
|
|
|
L<handler_name|/handler_name> attribute. |
2569
|
|
|
|
|
|
|
|
2570
|
|
|
|
|
|
|
=head2 call |
2571
|
|
|
|
|
|
|
|
2572
|
|
|
|
|
|
|
Usage: |
2573
|
|
|
|
|
|
|
<void> $cp->call( $handler, @optional_arguments ); |
2574
|
|
|
|
|
|
|
|
2575
|
|
|
|
|
|
|
The task of Handlers is to create Sections. Handlers can call other |
2576
|
|
|
|
|
|
|
Handlers to compose common Sections. |
2577
|
|
|
|
|
|
|
|
2578
|
|
|
|
|
|
|
Most Handlers know how to locate their peers because they reside in the |
2579
|
|
|
|
|
|
|
same package and have the same prefix conventions. B<call()> can |
2580
|
|
|
|
|
|
|
certainly be used to invoke peers, although it might seem like overkill. |
2581
|
|
|
|
|
|
|
|
2582
|
|
|
|
|
|
|
B<call()> is useful when Handlers reside in a hierarchy of packages and |
2583
|
|
|
|
|
|
|
you need a full search. B<call()> is also the only way to invoke |
2584
|
|
|
|
|
|
|
L<BUILTIN HANDLERS|/BUILTIN-HANDLERS:>. |
2585
|
|
|
|
|
|
|
|
2586
|
|
|
|
|
|
|
$cp->call( '*assertion_failure*', $description, \%status_vars ); |
2587
|
|
|
|
|
|
|
|
2588
|
|
|
|
|
|
|
B<call()> runs the algorithm described in L<HANDLER SEARCH|/HANDLER-SEARCH:>. |
2589
|
|
|
|
|
|
|
|
2590
|
|
|
|
|
|
|
=head2 contact_maintainer |
2591
|
|
|
|
|
|
|
|
2592
|
|
|
|
|
|
|
Usage: |
2593
|
|
|
|
|
|
|
<void> $cp->contact_maintainer(); |
2594
|
|
|
|
|
|
|
|
2595
|
|
|
|
|
|
|
If the L<maintainer|/maintainer> attribute is non-empty then a |
2596
|
|
|
|
|
|
|
Section containing the L<maintainer|/maintainer> string is |
2597
|
|
|
|
|
|
|
created. No Section is created if L<maintainer|/maintainer> is |
2598
|
|
|
|
|
|
|
empty. |
2599
|
|
|
|
|
|
|
|
2600
|
|
|
|
|
|
|
This works well if L<maintainer|/maintainer> contains contact |
2601
|
|
|
|
|
|
|
info. |
2602
|
|
|
|
|
|
|
|
2603
|
|
|
|
|
|
|
*** Please contact the maintainer *** |
2604
|
|
|
|
|
|
|
Your Name your.name@help.org (123)456-7890 |
2605
|
|
|
|
|
|
|
|
2606
|
|
|
|
|
|
|
=head2 decipher_child_error |
2607
|
|
|
|
|
|
|
|
2608
|
|
|
|
|
|
|
Usage: |
2609
|
|
|
|
|
|
|
<void> $cp->decipher_child_error(); |
2610
|
|
|
|
|
|
|
-or- |
2611
|
|
|
|
|
|
|
<void> $cp->decipher_child_error( $child_error ); |
2612
|
|
|
|
|
|
|
|
2613
|
|
|
|
|
|
|
Perl's B<$CHILD_ERROR> (B<$?>) encodes several bits of information about |
2614
|
|
|
|
|
|
|
how a child process terminates, see the B<perlvar> documentation on |
2615
|
|
|
|
|
|
|
B<$CHILD_ERROR> for details. B<decipher_child_error()> unpacks the |
2616
|
|
|
|
|
|
|
various bits of information in B<$CHILD_ERROR> and converts them into a |
2617
|
|
|
|
|
|
|
L<filled()|/filled> Section. Examples: |
2618
|
|
|
|
|
|
|
|
2619
|
|
|
|
|
|
|
*** Process Succeeded *** |
2620
|
|
|
|
|
|
|
The child process completed normally (exit code 0). |
2621
|
|
|
|
|
|
|
|
2622
|
|
|
|
|
|
|
*** Process returns failing status *** |
2623
|
|
|
|
|
|
|
The child process terminated with an exit code of 14. |
2624
|
|
|
|
|
|
|
|
2625
|
|
|
|
|
|
|
*** Process terminated by signal *** |
2626
|
|
|
|
|
|
|
The child process was terminated by SIGSEGV (signal 11). |
2627
|
|
|
|
|
|
|
|
2628
|
|
|
|
|
|
|
If a I<$child_error> argument is provided then the argument value is |
2629
|
|
|
|
|
|
|
deciphered, otherwise the value held in the L<child_error|/child_error> |
2630
|
|
|
|
|
|
|
attribute is used. |
2631
|
|
|
|
|
|
|
|
2632
|
|
|
|
|
|
|
=head2 directory |
2633
|
|
|
|
|
|
|
|
2634
|
|
|
|
|
|
|
Usage: |
2635
|
|
|
|
|
|
|
<void> $cp->directory( $dir <, $title >); |
2636
|
|
|
|
|
|
|
|
2637
|
|
|
|
|
|
|
The B<directory()> method creates a L<fixed()|/fixed> Section. The |
2638
|
|
|
|
|
|
|
optional I<$title>, if supplied, forms the title for the Section, |
2639
|
|
|
|
|
|
|
otherwise C<'Directory'> is used as the title. |
2640
|
|
|
|
|
|
|
|
2641
|
|
|
|
|
|
|
Output from B<Cwd::abs_path()> is used to form the body of the Section. |
2642
|
|
|
|
|
|
|
|
2643
|
|
|
|
|
|
|
=head2 errno_section |
2644
|
|
|
|
|
|
|
|
2645
|
|
|
|
|
|
|
Usage: |
2646
|
|
|
|
|
|
|
<void> $cp->errno_section( <$title> ); |
2647
|
|
|
|
|
|
|
|
2648
|
|
|
|
|
|
|
A filled Section is created using the contents of the |
2649
|
|
|
|
|
|
|
L<string_errno|/string_errno> attribute. If I<$title> is |
2650
|
|
|
|
|
|
|
not provided then 'System Diagnostic' is used as the Header title. |
2651
|
|
|
|
|
|
|
|
2652
|
|
|
|
|
|
|
No Section is created if the L<string_errno|/string_errno> |
2653
|
|
|
|
|
|
|
attribute is empty. |
2654
|
|
|
|
|
|
|
|
2655
|
|
|
|
|
|
|
=head2 filename |
2656
|
|
|
|
|
|
|
|
2657
|
|
|
|
|
|
|
Usage: |
2658
|
|
|
|
|
|
|
<void> $cp->filename( $file <, $title >); |
2659
|
|
|
|
|
|
|
|
2660
|
|
|
|
|
|
|
The B<filename()> method creates a L<fixed()|/fixed> Section. The |
2661
|
|
|
|
|
|
|
optional I<$title>, if supplied, forms the title for the Section, |
2662
|
|
|
|
|
|
|
otherwise C<'Filename'> is used as the title. |
2663
|
|
|
|
|
|
|
|
2664
|
|
|
|
|
|
|
Output from B<Cwd::abs_path()> is used to form the body of the Section. |
2665
|
|
|
|
|
|
|
|
2666
|
|
|
|
|
|
|
=head2 filled |
2667
|
|
|
|
|
|
|
|
2668
|
|
|
|
|
|
|
Usage: |
2669
|
|
|
|
|
|
|
<void> $cp->filled( $content <, $title >); |
2670
|
|
|
|
|
|
|
|
2671
|
|
|
|
|
|
|
B<filled()> creates a Section. The Section is introduced with a |
2672
|
|
|
|
|
|
|
L<header()|/header> containing I<$title>. The body of the Section is |
2673
|
|
|
|
|
|
|
produced by reformatting I<$content> into paragraphs of length-limited |
2674
|
|
|
|
|
|
|
lines. |
2675
|
|
|
|
|
|
|
|
2676
|
|
|
|
|
|
|
If I<$title> is not supplied, or if it is undef, then the |
2677
|
|
|
|
|
|
|
L<section_title|/section_title> attribute is used in its place. If |
2678
|
|
|
|
|
|
|
I<$title> is an empty string then no Header is produced. This makes it |
2679
|
|
|
|
|
|
|
easy to chain together Fixed and Filled Sections under the same Header. |
2680
|
|
|
|
|
|
|
|
2681
|
|
|
|
|
|
|
Any spaces at the beginning of each paragraph in I<$content> sets the |
2682
|
|
|
|
|
|
|
relative indentation for the whole paragraph. Each paragraph may have |
2683
|
|
|
|
|
|
|
different indentations. |
2684
|
|
|
|
|
|
|
|
2685
|
|
|
|
|
|
|
Paragraphs are reformatted by splitting them into words, on whitespace, then |
2686
|
|
|
|
|
|
|
building up new lines. Each line starts with spaces corresponding to the |
2687
|
|
|
|
|
|
|
sum of L<header_indent|/header_indent>, L<body_indent|/body_indent> and any |
2688
|
|
|
|
|
|
|
paragraph-specific indentation. Lines are then filled with words to achieve |
2689
|
|
|
|
|
|
|
a target line width. The target width is given by the L<columns|/columns> |
2690
|
|
|
|
|
|
|
attribute. |
2691
|
|
|
|
|
|
|
|
2692
|
|
|
|
|
|
|
In actuality, all the B<filled()> method does is to add a request for a |
2693
|
|
|
|
|
|
|
"filled_section" onto the end of the B<sections> list. The actual |
2694
|
|
|
|
|
|
|
processing is performed by L<filled_section()|/filled_section> when |
2695
|
|
|
|
|
|
|
L<render_message()|/render_message> traverses the B<sections> list. |
2696
|
|
|
|
|
|
|
What this means is that the settings for attributes like |
2697
|
|
|
|
|
|
|
L<section_title|/section_title>, L<columns|/columns>, |
2698
|
|
|
|
|
|
|
L<header_indent|/header_indent> and |
2699
|
|
|
|
|
|
|
L<body_indent|/body_indent> only come into play when |
2700
|
|
|
|
|
|
|
L<render_message()|/render_message> is run. |
2701
|
|
|
|
|
|
|
|
2702
|
|
|
|
|
|
|
See L<filled_section()|/filled_section> for details. |
2703
|
|
|
|
|
|
|
|
2704
|
|
|
|
|
|
|
=head2 filled_section |
2705
|
|
|
|
|
|
|
|
2706
|
|
|
|
|
|
|
Usage: |
2707
|
|
|
|
|
|
|
<String> $cp->filled_section( $content, $title ); |
2708
|
|
|
|
|
|
|
|
2709
|
|
|
|
|
|
|
B<filled_section()> is not usually invoked directly by users. |
2710
|
|
|
|
|
|
|
L<render_message()|/render_message> invokes B<filled_section()> as it |
2711
|
|
|
|
|
|
|
traverses the list held in the L<sections|/sections> attribute. |
2712
|
|
|
|
|
|
|
|
2713
|
|
|
|
|
|
|
I<$content> is expected to be a string. If I<$content> is an empty string |
2714
|
|
|
|
|
|
|
then no Section is produced - an empty string is returned. |
2715
|
|
|
|
|
|
|
|
2716
|
|
|
|
|
|
|
I<$title> is converted into a section-title using L<header()|/header>. |
2717
|
|
|
|
|
|
|
|
2718
|
|
|
|
|
|
|
I<$content> is split into paragraphs wherever there are two or more |
2719
|
|
|
|
|
|
|
consecutive newlines, more specifically using this regex: |
2720
|
|
|
|
|
|
|
|
2721
|
|
|
|
|
|
|
/(?: \r? \n ){2,}/x |
2722
|
|
|
|
|
|
|
|
2723
|
|
|
|
|
|
|
Each paragraph is examined for leading whitespace. This leading whitespace |
2724
|
|
|
|
|
|
|
is processed by converting tabs into spaces on eight-column boundarys. The |
2725
|
|
|
|
|
|
|
converted whitespace forms the supplemental indentation for the paragraph. |
2726
|
|
|
|
|
|
|
|
2727
|
|
|
|
|
|
|
New paragraphs are formed a line at a time by starting with an indentation |
2728
|
|
|
|
|
|
|
amount corresponding to the sum of L<header_indent|/header_indent>, |
2729
|
|
|
|
|
|
|
L<body_indent|/body_indent> and any supplemental indentation. Words from |
2730
|
|
|
|
|
|
|
the old paragraph are added to the line so long as the line length does not |
2731
|
|
|
|
|
|
|
exceed L<columns|/columns>. At least one word is always added, even if |
2732
|
|
|
|
|
|
|
L<columns|/columns> is exceeded. |
2733
|
|
|
|
|
|
|
|
2734
|
|
|
|
|
|
|
Any trailing whitespace is removed. Output paragraphs are joined with a |
2735
|
|
|
|
|
|
|
blank line. The returned string is the concatenation of the section title, |
2736
|
|
|
|
|
|
|
the paragraphs and a trailing blank line. |
2737
|
|
|
|
|
|
|
|
2738
|
|
|
|
|
|
|
Override B<filled_section()> in a sub-class, rather than |
2739
|
|
|
|
|
|
|
L<filled()|/filled>, if you want different filling behavior. |
2740
|
|
|
|
|
|
|
|
2741
|
|
|
|
|
|
|
=head2 fixed |
2742
|
|
|
|
|
|
|
|
2743
|
|
|
|
|
|
|
Usage: |
2744
|
|
|
|
|
|
|
<void> $cp->fixed( $content <, $title >); |
2745
|
|
|
|
|
|
|
|
2746
|
|
|
|
|
|
|
B<fixed()> creates a Section. The Section is introduced with a |
2747
|
|
|
|
|
|
|
L<header()|/header> containing I<$title>. The body of the Section is formed |
2748
|
|
|
|
|
|
|
by retaining the formatting already present in I<$content>. |
2749
|
|
|
|
|
|
|
|
2750
|
|
|
|
|
|
|
If I<$title> is not supplied, or if it is undef, then the |
2751
|
|
|
|
|
|
|
L<section_title|/section_title> attribute is used in its place. If |
2752
|
|
|
|
|
|
|
I<$title> is an empty string then no Header is included. This makes it easy |
2753
|
|
|
|
|
|
|
to chain together Fixed and Filled Sections under the same Header. |
2754
|
|
|
|
|
|
|
|
2755
|
|
|
|
|
|
|
Each line in I<$content> is indented by a constant amount corresponding to |
2756
|
|
|
|
|
|
|
the L<header_indent|/header_indent> plus the L<body_indent|/body_indent>. |
2757
|
|
|
|
|
|
|
Tabs in I<$content> are folded into spaces to preserve column alignment |
2758
|
|
|
|
|
|
|
before the indentation is prepended. Trailing whitespace on each line is |
2759
|
|
|
|
|
|
|
replaced with an appropriate line terminator for the platform. I<$content> |
2760
|
|
|
|
|
|
|
is otherwise unmolested. Almost WYSIWYG. |
2761
|
|
|
|
|
|
|
|
2762
|
|
|
|
|
|
|
In actuality, all the B<fixed()> method does is to add a request for a |
2763
|
|
|
|
|
|
|
"fixed_section" onto the end of the B<sections> list. The actual processing |
2764
|
|
|
|
|
|
|
is performed by the L<fixed_section()|/fixed_section> method when the |
2765
|
|
|
|
|
|
|
L<render_message()|/render_message> method traverses the B<sections> list. |
2766
|
|
|
|
|
|
|
What this means is that the settings for attributes like |
2767
|
|
|
|
|
|
|
L<section_title|/section_title>, L<header_indent|/header_indent> and |
2768
|
|
|
|
|
|
|
L<body_indent|/body_indent> only matter at the time |
2769
|
|
|
|
|
|
|
L<render_message()|/render_message> is run. |
2770
|
|
|
|
|
|
|
|
2771
|
|
|
|
|
|
|
See L<fixed_section()|/fixed_section> for details. |
2772
|
|
|
|
|
|
|
|
2773
|
|
|
|
|
|
|
=head2 fixed_section |
2774
|
|
|
|
|
|
|
|
2775
|
|
|
|
|
|
|
Usage: |
2776
|
|
|
|
|
|
|
<String> $cp->fixed_section( $content, $title ); |
2777
|
|
|
|
|
|
|
|
2778
|
|
|
|
|
|
|
B<fixed_section()> is not usually invoked directly by users. |
2779
|
|
|
|
|
|
|
L<render_message()|/render_message> invokes B<fixed_section()> as |
2780
|
|
|
|
|
|
|
it traverses the list in the L<sections|/sections> attribute. |
2781
|
|
|
|
|
|
|
|
2782
|
|
|
|
|
|
|
I<$content> is expected to be a string. If I<$content> is the empty |
2783
|
|
|
|
|
|
|
string then no Section is generated and an empty string is returned. |
2784
|
|
|
|
|
|
|
|
2785
|
|
|
|
|
|
|
I<$title> is converted into a Section title string using |
2786
|
|
|
|
|
|
|
L<header()|/header>. |
2787
|
|
|
|
|
|
|
|
2788
|
|
|
|
|
|
|
I<$content> is split into lines on newline ("\n") characters for |
2789
|
|
|
|
|
|
|
processing. Trailing whitespace is removed. Embedded tabs are converted |
2790
|
|
|
|
|
|
|
to the equivalent number of spaces assuming eight character boundarys. |
2791
|
|
|
|
|
|
|
Indentation corresponding to the sum of |
2792
|
|
|
|
|
|
|
L<header_indent|/header_indent> and |
2793
|
|
|
|
|
|
|
L<body_indent|/body_indent> is added to the beginning of each |
2794
|
|
|
|
|
|
|
line. Lines are joined with platform-appropriate line termination. |
2795
|
|
|
|
|
|
|
|
2796
|
|
|
|
|
|
|
Trailing whitespace is removed, the section-title is prepended and a |
2797
|
|
|
|
|
|
|
single blank line is added to the end. |
2798
|
|
|
|
|
|
|
|
2799
|
|
|
|
|
|
|
=head2 header |
2800
|
|
|
|
|
|
|
|
2801
|
|
|
|
|
|
|
Usage: |
2802
|
|
|
|
|
|
|
<String> $cp->header( $title ); |
2803
|
|
|
|
|
|
|
|
2804
|
|
|
|
|
|
|
B<header()> produces an introductory line for a Section of paragraphs. |
2805
|
|
|
|
|
|
|
The line is indented from the left margin by |
2806
|
|
|
|
|
|
|
L<header_indent|/header_indent> spaces. The line is formed |
2807
|
|
|
|
|
|
|
using the following template: |
2808
|
|
|
|
|
|
|
|
2809
|
|
|
|
|
|
|
<indent>*** <$title> *** |
2810
|
|
|
|
|
|
|
|
2811
|
|
|
|
|
|
|
The intent is to provide an introductory heading for Section paragraphs. |
2812
|
|
|
|
|
|
|
|
2813
|
|
|
|
|
|
|
*** Description *** |
2814
|
|
|
|
|
|
|
The database server is refusing connections. |
2815
|
|
|
|
|
|
|
|
2816
|
|
|
|
|
|
|
If I<$title> is undef then the L<section_title|/section_title> |
2817
|
|
|
|
|
|
|
attribute is used in its place. Passing an empty string (C<''>) for |
2818
|
|
|
|
|
|
|
I<title> causes B<header()> to omit Header generation. In this case an |
2819
|
|
|
|
|
|
|
empty string is returned. |
2820
|
|
|
|
|
|
|
|
2821
|
|
|
|
|
|
|
B<header()> is called by the Section creating methods |
2822
|
|
|
|
|
|
|
L<filled_section()|/filled_section> and |
2823
|
|
|
|
|
|
|
L<fixed_section()|/fixed_section>. |
2824
|
|
|
|
|
|
|
|
2825
|
|
|
|
|
|
|
Subclass B<Carp::Proxy> and override B<header()> for a different look. |
2826
|
|
|
|
|
|
|
|
2827
|
|
|
|
|
|
|
=head2 identifier_presentation |
2828
|
|
|
|
|
|
|
|
2829
|
|
|
|
|
|
|
Usage: |
2830
|
|
|
|
|
|
|
<String> $class->identifier_presentation( $name ); |
2831
|
|
|
|
|
|
|
|
2832
|
|
|
|
|
|
|
The Banner reads better when words in the |
2833
|
|
|
|
|
|
|
L<handler_name|/handler_name> are separated by spaces rather |
2834
|
|
|
|
|
|
|
than underscores (C<_>). Likewise with camelCasedIdentifiers. |
2835
|
|
|
|
|
|
|
|
2836
|
|
|
|
|
|
|
Underscores are replaced by single spaces everywhere they occur. Spaces |
2837
|
|
|
|
|
|
|
are inserted everywhere character-case changes from lower to upper, and |
2838
|
|
|
|
|
|
|
upper-case characters are folded to lower-case. The following are example |
2839
|
|
|
|
|
|
|
conversions: |
2840
|
|
|
|
|
|
|
|
2841
|
|
|
|
|
|
|
'no_user_credentials' => 'no user credentials' |
2842
|
|
|
|
|
|
|
'nonexistentRecord' => 'nonexistent record' |
2843
|
|
|
|
|
|
|
|
2844
|
|
|
|
|
|
|
Sub-class B<Carp::Proxy> and override B<identifier_presentation()> if |
2845
|
|
|
|
|
|
|
you want a different convention. |
2846
|
|
|
|
|
|
|
|
2847
|
|
|
|
|
|
|
=head2 import |
2848
|
|
|
|
|
|
|
|
2849
|
|
|
|
|
|
|
Usage: |
2850
|
|
|
|
|
|
|
<void> $class->import( <%attrs_by_proxy>); |
2851
|
|
|
|
|
|
|
|
2852
|
|
|
|
|
|
|
B<import()> accepts specifications for Proxy construction. Specifications |
2853
|
|
|
|
|
|
|
take the form of a proxyname and a hashref of attribute initializations. |
2854
|
|
|
|
|
|
|
|
2855
|
|
|
|
|
|
|
proxyname1 => { |
2856
|
|
|
|
|
|
|
attributeA => initial_valueA, |
2857
|
|
|
|
|
|
|
attributeB => initial_valueB, |
2858
|
|
|
|
|
|
|
... |
2859
|
|
|
|
|
|
|
} |
2860
|
|
|
|
|
|
|
|
2861
|
|
|
|
|
|
|
Any number of proxyname, hashref pairs may be specified; a proxy subroutine |
2862
|
|
|
|
|
|
|
will be constructed for each pair. |
2863
|
|
|
|
|
|
|
|
2864
|
|
|
|
|
|
|
If there is only one argument it is taken to be a proxyname introducing an |
2865
|
|
|
|
|
|
|
empty hashref. If there are no arguments then it is assumed that the |
2866
|
|
|
|
|
|
|
builder-specified default for the L<proxy_name|/proxy_name> attribute |
2867
|
|
|
|
|
|
|
(C<'fatal'>), should be used for the proxyname and an empty hashref used for |
2868
|
|
|
|
|
|
|
the attribute initializations. |
2869
|
|
|
|
|
|
|
|
2870
|
|
|
|
|
|
|
B<import()> probes the callstack to determine the package and filename of |
2871
|
|
|
|
|
|
|
the user code that called B<import()>. B<import()> uses these values to create |
2872
|
|
|
|
|
|
|
a hash containing the attributes L<proxy_filename|/proxy_filename>, |
2873
|
|
|
|
|
|
|
L<proxy_name|/proxy_name> L<proxy_package|/proxy_package> and |
2874
|
|
|
|
|
|
|
L<fq_proxy_name|/fq_proxy_name>. Any supplied attributes are added to the |
2875
|
|
|
|
|
|
|
hash. The builtin handler L<*configuration*|/configuration> returns a |
2876
|
|
|
|
|
|
|
reference to this hash. |
2877
|
|
|
|
|
|
|
|
2878
|
|
|
|
|
|
|
=head2 list_handler_packages |
2879
|
|
|
|
|
|
|
|
2880
|
|
|
|
|
|
|
Usage: |
2881
|
|
|
|
|
|
|
<list> $cp->list_handler_packages(); |
2882
|
|
|
|
|
|
|
|
2883
|
|
|
|
|
|
|
B<list_handler_packages()> is sugar that dereferences the |
2884
|
|
|
|
|
|
|
L<handler_pkgs|/handler_pkgs> attribute (an ArrayRef) and |
2885
|
|
|
|
|
|
|
returns the contents. |
2886
|
|
|
|
|
|
|
|
2887
|
|
|
|
|
|
|
=head2 list_sections |
2888
|
|
|
|
|
|
|
|
2889
|
|
|
|
|
|
|
Usage: |
2890
|
|
|
|
|
|
|
<list> $cp->list_sections(); |
2891
|
|
|
|
|
|
|
|
2892
|
|
|
|
|
|
|
The L<sections|/sections> attribute is an ArrayRef. |
2893
|
|
|
|
|
|
|
B<list_sections()> is sugar to return all the elements of |
2894
|
|
|
|
|
|
|
L<sections|/sections>. |
2895
|
|
|
|
|
|
|
|
2896
|
|
|
|
|
|
|
=head2 new |
2897
|
|
|
|
|
|
|
|
2898
|
|
|
|
|
|
|
Usage: |
2899
|
|
|
|
|
|
|
<Carp::Proxy object> $class->new |
2900
|
|
|
|
|
|
|
( arg => harvested $_, |
2901
|
|
|
|
|
|
|
eval_error => harvested $@, |
2902
|
|
|
|
|
|
|
fq_proxy_name => 'package::subname', |
2903
|
|
|
|
|
|
|
handler_name => 'name of handler', |
2904
|
|
|
|
|
|
|
numeric_errno => harvested 0 + $!, |
2905
|
|
|
|
|
|
|
proxy_filename => 'filename', |
2906
|
|
|
|
|
|
|
proxy_name => 'subname', |
2907
|
|
|
|
|
|
|
proxy_package => 'package', |
2908
|
|
|
|
|
|
|
string_errno => harvested '' . $!, |
2909
|
|
|
|
|
|
|
< attribute => value ...> |
2910
|
|
|
|
|
|
|
); |
2911
|
|
|
|
|
|
|
|
2912
|
|
|
|
|
|
|
I<new()> is normally called by the Proxy, so this documentation is only |
2913
|
|
|
|
|
|
|
useful if you are using the object for your own purposes. There are a large |
2914
|
|
|
|
|
|
|
number of required attribute-value pairs. Specification for any additional |
2915
|
|
|
|
|
|
|
attributes is supported. Builder methods are invoked for all unspecified |
2916
|
|
|
|
|
|
|
attributes. |
2917
|
|
|
|
|
|
|
|
2918
|
|
|
|
|
|
|
There is some inconsistency around the L<proxy_name|/proxy_name> attribute. |
2919
|
|
|
|
|
|
|
The L<proxy_name|/proxy_name> is required by I<new()> even though it has a |
2920
|
|
|
|
|
|
|
builder method. The builder is for use by L<import()|/import>, which |
2921
|
|
|
|
|
|
|
invokes it if needed, and passes the result to new(). |
2922
|
|
|
|
|
|
|
|
2923
|
|
|
|
|
|
|
=head2 perform_disposition |
2924
|
|
|
|
|
|
|
|
2925
|
|
|
|
|
|
|
Usage: |
2926
|
|
|
|
|
|
|
<Scalar> $cp->perform_disposition(); |
2927
|
|
|
|
|
|
|
|
2928
|
|
|
|
|
|
|
The L<disposition|/disposition> attribute determines the final |
2929
|
|
|
|
|
|
|
actions of the Proxy, which are carried out by B<perform_disposition()>. |
2930
|
|
|
|
|
|
|
Valid settings for L<disposition|/disposition> are: |
2931
|
|
|
|
|
|
|
|
2932
|
|
|
|
|
|
|
=over 4 |
2933
|
|
|
|
|
|
|
|
2934
|
|
|
|
|
|
|
=item B<'warn'> |
2935
|
|
|
|
|
|
|
|
2936
|
|
|
|
|
|
|
A I<disposition> of C<'warn'> causes B<perform_disposition()> to do this: |
2937
|
|
|
|
|
|
|
|
2938
|
|
|
|
|
|
|
warn $cp; |
2939
|
|
|
|
|
|
|
return (); |
2940
|
|
|
|
|
|
|
|
2941
|
|
|
|
|
|
|
=item B<'die'> |
2942
|
|
|
|
|
|
|
|
2943
|
|
|
|
|
|
|
A I<disposition> of C<'die'> causes B<perform_disposition()> to do this: |
2944
|
|
|
|
|
|
|
|
2945
|
|
|
|
|
|
|
$ERRNO = $cp->exit_code; |
2946
|
|
|
|
|
|
|
die $cp; |
2947
|
|
|
|
|
|
|
|
2948
|
|
|
|
|
|
|
See Perl's B<die()> for an explanation of propagating $ERRNO into the exit |
2949
|
|
|
|
|
|
|
code for the process. |
2950
|
|
|
|
|
|
|
|
2951
|
|
|
|
|
|
|
C<'die'> is the default I<disposition>. |
2952
|
|
|
|
|
|
|
|
2953
|
|
|
|
|
|
|
=item B<'return'> |
2954
|
|
|
|
|
|
|
|
2955
|
|
|
|
|
|
|
The I<disposition> of C<'return'> is unusual; it signifies a desire to |
2956
|
|
|
|
|
|
|
abort the whole death-by-proxy process. B<perform_disposition> does this: |
2957
|
|
|
|
|
|
|
|
2958
|
|
|
|
|
|
|
return $cp; |
2959
|
|
|
|
|
|
|
|
2960
|
|
|
|
|
|
|
=item B<CodeRef> |
2961
|
|
|
|
|
|
|
|
2962
|
|
|
|
|
|
|
The user can take control of disposition by supplying a CodeRef for |
2963
|
|
|
|
|
|
|
I<disposition>. In this case, the behavior of B<perform_disposition()> |
2964
|
|
|
|
|
|
|
is: |
2965
|
|
|
|
|
|
|
|
2966
|
|
|
|
|
|
|
return $cp->disposition->( $cp ); |
2967
|
|
|
|
|
|
|
|
2968
|
|
|
|
|
|
|
=back |
2969
|
|
|
|
|
|
|
|
2970
|
|
|
|
|
|
|
=head2 prepend_handler_package |
2971
|
|
|
|
|
|
|
|
2972
|
|
|
|
|
|
|
Usage: |
2973
|
|
|
|
|
|
|
<void> $cp->prepend_handler_package( $pkg <, $pkg2...>); |
2974
|
|
|
|
|
|
|
|
2975
|
|
|
|
|
|
|
The attribute L<handler_pkgs|/handler_pkgs> is an ArrayRef. |
2976
|
|
|
|
|
|
|
B<prepend_handler_package()> is sugar to make adding packages to the front |
2977
|
|
|
|
|
|
|
of L<handler_pkgs|/handler_pkgs> easier. |
2978
|
|
|
|
|
|
|
|
2979
|
|
|
|
|
|
|
=head2 prepend_section |
2980
|
|
|
|
|
|
|
|
2981
|
|
|
|
|
|
|
Usage: |
2982
|
|
|
|
|
|
|
<void> $cp->prepend_section( $array_ref <, $array_ref2...>); |
2983
|
|
|
|
|
|
|
|
2984
|
|
|
|
|
|
|
The L<sections|/sections> attribute is an ArrayRef containing |
2985
|
|
|
|
|
|
|
child ArrayRefs, one for each Section (like filled(), fixed() etc.). |
2986
|
|
|
|
|
|
|
B<prepend_section()> is sugar to make adding a Section request to the |
2987
|
|
|
|
|
|
|
L<sections|/sections> attribute, easier. Section requests are |
2988
|
|
|
|
|
|
|
added to the front of L<sections|/sections> (prepended). |
2989
|
|
|
|
|
|
|
|
2990
|
|
|
|
|
|
|
=head2 raw |
2991
|
|
|
|
|
|
|
|
2992
|
|
|
|
|
|
|
Usage: |
2993
|
|
|
|
|
|
|
<void> $cp->raw( $content ); |
2994
|
|
|
|
|
|
|
|
2995
|
|
|
|
|
|
|
B<raw()> provides an alternative to L<fixed()|/fixed> and |
2996
|
|
|
|
|
|
|
L<filled()|/filled> for composing diagnostic Sections. |
2997
|
|
|
|
|
|
|
|
2998
|
|
|
|
|
|
|
In effect, B<raw()> creates a Section containing only B<$content>. |
2999
|
|
|
|
|
|
|
You are completely responsible for the final appearance of the Section; |
3000
|
|
|
|
|
|
|
there is no Header, no trailing blank line, no indentation and no |
3001
|
|
|
|
|
|
|
platform appropriate line termination. |
3002
|
|
|
|
|
|
|
|
3003
|
|
|
|
|
|
|
In actuality, all the B<raw()> method does is to add a request for a raw |
3004
|
|
|
|
|
|
|
Section onto the B<sections> list; the actual processing is performed by |
3005
|
|
|
|
|
|
|
the L<raw_section()|/raw_section> method when the |
3006
|
|
|
|
|
|
|
L<render_message()|/render_message> traverses B<sections>. |
3007
|
|
|
|
|
|
|
|
3008
|
|
|
|
|
|
|
See L<raw_section()|/raw_section> for details. |
3009
|
|
|
|
|
|
|
|
3010
|
|
|
|
|
|
|
=head2 raw_section |
3011
|
|
|
|
|
|
|
|
3012
|
|
|
|
|
|
|
Usage: |
3013
|
|
|
|
|
|
|
<String> $cp->raw_section( $content ); |
3014
|
|
|
|
|
|
|
|
3015
|
|
|
|
|
|
|
B<raw_section()> is not usually invoked directly by users. |
3016
|
|
|
|
|
|
|
L<render_message()|/render_message> invokes B<raw_section()> as it |
3017
|
|
|
|
|
|
|
traverses the list in the L<sections|/sections> attribute. |
3018
|
|
|
|
|
|
|
|
3019
|
|
|
|
|
|
|
B<raw_section()> does nothing; the returned string is simply a copy of |
3020
|
|
|
|
|
|
|
I<$content>. |
3021
|
|
|
|
|
|
|
|
3022
|
|
|
|
|
|
|
=head2 render_message |
3023
|
|
|
|
|
|
|
|
3024
|
|
|
|
|
|
|
Usage: |
3025
|
|
|
|
|
|
|
<String> $cp->render_message(); |
3026
|
|
|
|
|
|
|
|
3027
|
|
|
|
|
|
|
The behavior of B<render_message()> is dependent on the setting of the |
3028
|
|
|
|
|
|
|
attribute L<as_yaml|/as_yaml>. If L<as_yaml|/as_yaml> is False, which is |
3029
|
|
|
|
|
|
|
the default, then B<render_message()> walks the list of |
3030
|
|
|
|
|
|
|
section-specifications stored in the L<sections|/sections> attribute, |
3031
|
|
|
|
|
|
|
executing each one in turn. The return value is formed by concatenating |
3032
|
|
|
|
|
|
|
each of the results. |
3033
|
|
|
|
|
|
|
|
3034
|
|
|
|
|
|
|
The L<sections|/sections> attribute, an ArrayRef, is expected to contain any |
3035
|
|
|
|
|
|
|
number of ArrayRef elements. Each child ArrayRef must have at least one |
3036
|
|
|
|
|
|
|
element: the name of a method to be invoked. Any remaining elements are |
3037
|
|
|
|
|
|
|
passed to the invoked method as arguments. For example, a |
3038
|
|
|
|
|
|
|
L<sections|/sections> specification that looks like this: |
3039
|
|
|
|
|
|
|
|
3040
|
|
|
|
|
|
|
[ |
3041
|
|
|
|
|
|
|
[ 'filled_section', 'content1', 'title1' ], |
3042
|
|
|
|
|
|
|
[ 'filled_section', 'content2', 'title2' ], |
3043
|
|
|
|
|
|
|
] |
3044
|
|
|
|
|
|
|
|
3045
|
|
|
|
|
|
|
Results in the execution of something like this: |
3046
|
|
|
|
|
|
|
|
3047
|
|
|
|
|
|
|
my $buffer = $cp->banner(); |
3048
|
|
|
|
|
|
|
|
3049
|
|
|
|
|
|
|
$buffer .= $cp->filled_section( 'content1', 'title1' ); |
3050
|
|
|
|
|
|
|
$buffer .= $cp->filled_section( 'content2', 'title2' ); |
3051
|
|
|
|
|
|
|
|
3052
|
|
|
|
|
|
|
return $buffer; |
3053
|
|
|
|
|
|
|
|
3054
|
|
|
|
|
|
|
The L<sections|/sections> list is unchanged by the traversal, so |
3055
|
|
|
|
|
|
|
B<render_message()> may be invoked repeatedly. Settings for attributes like |
3056
|
|
|
|
|
|
|
L<banner_title|/banner_title>, L<columns|/columns>, |
3057
|
|
|
|
|
|
|
L<section_title|/section_title>, L<header_indent|/header_indent> and |
3058
|
|
|
|
|
|
|
L<body_indent|/body_indent> can be changed between invocations to vary the |
3059
|
|
|
|
|
|
|
message format. |
3060
|
|
|
|
|
|
|
|
3061
|
|
|
|
|
|
|
Changing attributes like L<context|/context>, which are |
3062
|
|
|
|
|
|
|
referenced during the generation of Section specifications, have no effect. |
3063
|
|
|
|
|
|
|
|
3064
|
|
|
|
|
|
|
If L<as_yaml|/as_yaml> is True then we return a string that |
3065
|
|
|
|
|
|
|
is a YAML dump of the B<Carp::Proxy> object, something like this: |
3066
|
|
|
|
|
|
|
|
3067
|
|
|
|
|
|
|
return YAML::XS::Dump( $cp ); |
3068
|
|
|
|
|
|
|
|
3069
|
|
|
|
|
|
|
The intent here is to use YAML to serialize all aspects of the |
3070
|
|
|
|
|
|
|
B<Carp::Proxy> object. Assuming that we have a |
3071
|
|
|
|
|
|
|
L<disposition|/disposition> setting of B<die>, our |
3072
|
|
|
|
|
|
|
serialized object will be written out to STDERR, where it can be captured |
3073
|
|
|
|
|
|
|
by a parent process and reconstituted. The reconstituted object can |
3074
|
|
|
|
|
|
|
be examined, or augmented with parental context and rethrown. |
3075
|
|
|
|
|
|
|
|
3076
|
|
|
|
|
|
|
=head2 synopsis |
3077
|
|
|
|
|
|
|
|
3078
|
|
|
|
|
|
|
Usage: |
3079
|
|
|
|
|
|
|
<void> $cp->synopsis( %optional_supplements ); |
3080
|
|
|
|
|
|
|
|
3081
|
|
|
|
|
|
|
The B<synopsis()> method employs B<Pod::Usage::pod2usage()> to create a |
3082
|
|
|
|
|
|
|
Section from the user's POD. User POD is located by searching in the |
3083
|
|
|
|
|
|
|
L<pod_filename|/pod_filename> attribute. |
3084
|
|
|
|
|
|
|
|
3085
|
|
|
|
|
|
|
The call to B<pod2usage()> is passed a HashRef with the following options: |
3086
|
|
|
|
|
|
|
|
3087
|
|
|
|
|
|
|
-input => $cp->pod_filename, |
3088
|
|
|
|
|
|
|
-output => <filehandle>, |
3089
|
|
|
|
|
|
|
-exitval => 'NOEXIT', |
3090
|
|
|
|
|
|
|
-verbose => 0, |
3091
|
|
|
|
|
|
|
|
3092
|
|
|
|
|
|
|
This set of options causes B<pod2usage()> to format the B<SYNOPSIS> |
3093
|
|
|
|
|
|
|
portion of the user's POD. Any key-value pairs in |
3094
|
|
|
|
|
|
|
B<%optional_supplements> are appended to the contents of the HashRef, |
3095
|
|
|
|
|
|
|
allowing you to override or supplement these defaults. |
3096
|
|
|
|
|
|
|
|
3097
|
|
|
|
|
|
|
=head3 Example |
3098
|
|
|
|
|
|
|
|
3099
|
|
|
|
|
|
|
Internally, B<Carp::Proxy> uses B<synopsis()> to extract sections from this |
3100
|
|
|
|
|
|
|
POD document when composing diagnostics. If, for instance, you supply a |
3101
|
|
|
|
|
|
|
negative value as the setting for L<body_indent|/body_indent> you get an |
3102
|
|
|
|
|
|
|
exception. The text of the exception is generated using something like |
3103
|
|
|
|
|
|
|
this: |
3104
|
|
|
|
|
|
|
|
3105
|
|
|
|
|
|
|
$cp->synopsis( -verbose => 99, |
3106
|
|
|
|
|
|
|
-sections => ["ATTRIBUTES/body_indent"], |
3107
|
|
|
|
|
|
|
); |
3108
|
|
|
|
|
|
|
|
3109
|
|
|
|
|
|
|
The resulting diagnostic looks something like this: |
3110
|
|
|
|
|
|
|
|
3111
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
3112
|
|
|
|
|
|
|
Oops << negative body indentation >> |
3113
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
3114
|
|
|
|
|
|
|
*** Description *** |
3115
|
|
|
|
|
|
|
The requested setting of '-1' for the 'body_indent' |
3116
|
|
|
|
|
|
|
attribute is not allowed. |
3117
|
|
|
|
|
|
|
|
3118
|
|
|
|
|
|
|
*** Synopsis *** |
3119
|
|
|
|
|
|
|
body_indent: |
3120
|
|
|
|
|
|
|
*body_indent* influences the presentation of paragraphs |
3121
|
|
|
|
|
|
|
created by the Section creating methods filled() and |
3122
|
|
|
|
|
|
|
fixed(). Use *body_indent* to determine the amount of |
3123
|
|
|
|
|
|
|
additional indentation, beyond header_indent, that is |
3124
|
|
|
|
|
|
|
applied to Section paragraphs. |
3125
|
|
|
|
|
|
|
|
3126
|
|
|
|
|
|
|
Builder: _build_body_indent() |
3127
|
|
|
|
|
|
|
Default: 2 |
3128
|
|
|
|
|
|
|
Domain: Non-negative integers |
3129
|
|
|
|
|
|
|
Affects: filled_section() and fixed_section() |
3130
|
|
|
|
|
|
|
Mutability: Read-Write |
3131
|
|
|
|
|
|
|
|
3132
|
|
|
|
|
|
|
*** Stacktrace *** |
3133
|
|
|
|
|
|
|
... |
3134
|
|
|
|
|
|
|
|
3135
|
|
|
|
|
|
|
See L<'perldoc Pod::Usage'|Pod::Usage> and |
3136
|
|
|
|
|
|
|
L<'perldoc Pod::Select'|Pod::Select> for details about using B<-verbose> |
3137
|
|
|
|
|
|
|
and B<-sections>. |
3138
|
|
|
|
|
|
|
|
3139
|
|
|
|
|
|
|
=head2 usage |
3140
|
|
|
|
|
|
|
|
3141
|
|
|
|
|
|
|
Usage: |
3142
|
|
|
|
|
|
|
<void> $cp->usage(); |
3143
|
|
|
|
|
|
|
|
3144
|
|
|
|
|
|
|
B<usage()> examines the callstack, to find the invoker - the subroutine |
3145
|
|
|
|
|
|
|
that invoked the Proxy. A pass through the |
3146
|
|
|
|
|
|
|
L<HANDLER SEARCH|/HANDLER-SEARCH:> algorithm is made to see if it can find |
3147
|
|
|
|
|
|
|
a subroutine with this name: |
3148
|
|
|
|
|
|
|
|
3149
|
|
|
|
|
|
|
usage_<invoker> |
3150
|
|
|
|
|
|
|
|
3151
|
|
|
|
|
|
|
In the default configuration this means that these three subroutine |
3152
|
|
|
|
|
|
|
names are tested for existence: |
3153
|
|
|
|
|
|
|
|
3154
|
|
|
|
|
|
|
<package>::_cp_usage_<invoker> |
3155
|
|
|
|
|
|
|
<package>::_usage_<invoker> |
3156
|
|
|
|
|
|
|
<package>::usage_<invoker> |
3157
|
|
|
|
|
|
|
|
3158
|
|
|
|
|
|
|
Just like the search for a Handler, the settings for |
3159
|
|
|
|
|
|
|
L<handler_prefix|/handler_prefix> and |
3160
|
|
|
|
|
|
|
L<handler_pkgs|/handler_pkgs> influence the where and what of |
3161
|
|
|
|
|
|
|
the search for a usage subroutine. |
3162
|
|
|
|
|
|
|
|
3163
|
|
|
|
|
|
|
If none of the attempts finds an existing subroutine then the next entry in |
3164
|
|
|
|
|
|
|
the callstack (i.e. the invoker of the invoker) is tried. The progression |
3165
|
|
|
|
|
|
|
up the callstack continues until there are no more stackframes. At this |
3166
|
|
|
|
|
|
|
point the algorithm gives up and throws a "no usage documentation" exception. |
3167
|
|
|
|
|
|
|
|
3168
|
|
|
|
|
|
|
The search sounds complex, but the intent is simple: public subroutines |
3169
|
|
|
|
|
|
|
and methods can call utilities, say to validate incoming arguments, and |
3170
|
|
|
|
|
|
|
these utilities can call Proxys to throw exceptions. When the Handler |
3171
|
|
|
|
|
|
|
invokes B<usage()> we eventually find a usage message associated with the |
3172
|
|
|
|
|
|
|
public subroutine. |
3173
|
|
|
|
|
|
|
|
3174
|
|
|
|
|
|
|
#----- We want this to be called for help with 'my_func()' |
3175
|
|
|
|
|
|
|
sub _usage_my_func { |
3176
|
|
|
|
|
|
|
my( $cp ) = @_; |
3177
|
|
|
|
|
|
|
|
3178
|
|
|
|
|
|
|
$cp->fixed( 'Usage: <num> my_func( val );', 'Usage' ); |
3179
|
|
|
|
|
|
|
$cp->filled( 'my_func() returns blah blah blah.', '' ); |
3180
|
|
|
|
|
|
|
} |
3181
|
|
|
|
|
|
|
|
3182
|
|
|
|
|
|
|
sub my_func { |
3183
|
|
|
|
|
|
|
my( $val ) = @_; |
3184
|
|
|
|
|
|
|
|
3185
|
|
|
|
|
|
|
fatal 'missing_argument', 'val' |
3186
|
|
|
|
|
|
|
if not defined $val; |
3187
|
|
|
|
|
|
|
... |
3188
|
|
|
|
|
|
|
} |
3189
|
|
|
|
|
|
|
|
3190
|
|
|
|
|
|
|
#----- Reusable by anyone that defines their own _usage_ |
3191
|
|
|
|
|
|
|
sub _cp_missing_argument { |
3192
|
|
|
|
|
|
|
my( $cp, $name ) = @_; |
3193
|
|
|
|
|
|
|
|
3194
|
|
|
|
|
|
|
$cp->filled("The argument '$name' is missing, or undef."); |
3195
|
|
|
|
|
|
|
$cp->usage; |
3196
|
|
|
|
|
|
|
} |
3197
|
|
|
|
|
|
|
|
3198
|
|
|
|
|
|
|
Other subroutines, besides my_func(), can throw fatal exceptions with the |
3199
|
|
|
|
|
|
|
'missing_argument' Handler. The diagnostic will be customized |
3200
|
|
|
|
|
|
|
appropriately for each one. |
3201
|
|
|
|
|
|
|
|
3202
|
|
|
|
|
|
|
The invoker-upward aspect of the search means that B<my_func()>, instead |
3203
|
|
|
|
|
|
|
of calling B<fatal()> directly, could have called an arg-checking utility, |
3204
|
|
|
|
|
|
|
which called another utility etc., which finally called B<fatal()>. The |
3205
|
|
|
|
|
|
|
search would have eventually located B<_usage_my_func()>. |
3206
|
|
|
|
|
|
|
|
3207
|
|
|
|
|
|
|
=head1 HANDLER SEARCH |
3208
|
|
|
|
|
|
|
|
3209
|
|
|
|
|
|
|
A Proxy invocation contains, as its first argument, a string that will |
3210
|
|
|
|
|
|
|
become the L<handler_name|/handler_name> attribute. The string |
3211
|
|
|
|
|
|
|
C<'no_such_author'> is used to establish |
3212
|
|
|
|
|
|
|
L<handler_name|/handler_name> in this example: |
3213
|
|
|
|
|
|
|
|
3214
|
|
|
|
|
|
|
fatal 'no_such_author', $who; |
3215
|
|
|
|
|
|
|
|
3216
|
|
|
|
|
|
|
The Proxy calls the Handler to build up the diagnostic message, but first |
3217
|
|
|
|
|
|
|
it must locate the requested subroutine. |
3218
|
|
|
|
|
|
|
|
3219
|
|
|
|
|
|
|
The search for a Handler subroutine is made in the packages found in |
3220
|
|
|
|
|
|
|
L<handler_pkgs|/handler_pkgs>. Users can specify a list of |
3221
|
|
|
|
|
|
|
packages to search by supplying the tagged list to B<use()> or |
3222
|
|
|
|
|
|
|
L<import()|/import>. |
3223
|
|
|
|
|
|
|
|
3224
|
|
|
|
|
|
|
package main; |
3225
|
|
|
|
|
|
|
use Carp::Proxy fatal => { handler_pkgs => [qw( Support Common )]}; |
3226
|
|
|
|
|
|
|
|
3227
|
|
|
|
|
|
|
You can also sub-class B<Carp::Proxy> and override |
3228
|
|
|
|
|
|
|
B<_build_handler_pkgs()> to return an ArrayRef of the desired packages. |
3229
|
|
|
|
|
|
|
|
3230
|
|
|
|
|
|
|
The Proxy always appends a copy of |
3231
|
|
|
|
|
|
|
L<proxy_package|/proxy_package> to |
3232
|
|
|
|
|
|
|
L<handler_pkgs|/handler_pkgs> after object construction. |
3233
|
|
|
|
|
|
|
L<proxy_package|/proxy_package> is the package that issued the |
3234
|
|
|
|
|
|
|
B<use()>, or made the call to L<import()|/import>. In the above example |
3235
|
|
|
|
|
|
|
L<handler_pkgs|/handler_pkgs> becomes: |
3236
|
|
|
|
|
|
|
|
3237
|
|
|
|
|
|
|
[qw( Support Common main )] |
3238
|
|
|
|
|
|
|
|
3239
|
|
|
|
|
|
|
The subroutine that is the target of the search is influenced by the |
3240
|
|
|
|
|
|
|
setting of L<handler_prefix|/handler_prefix>. When the |
3241
|
|
|
|
|
|
|
L<handler_prefix|/handler_prefix> attribute is undef, the Proxy |
3242
|
|
|
|
|
|
|
builds three templates from L<handler_name|/handler_name>. The |
3243
|
|
|
|
|
|
|
first subroutine that exists is used as the Handler. |
3244
|
|
|
|
|
|
|
|
3245
|
|
|
|
|
|
|
<package>::_cp_<handler_name> |
3246
|
|
|
|
|
|
|
<package>::_<handler_name> |
3247
|
|
|
|
|
|
|
<package>::<handler_name> |
3248
|
|
|
|
|
|
|
|
3249
|
|
|
|
|
|
|
If L<handler_prefix|/handler_prefix> is not undef then only one |
3250
|
|
|
|
|
|
|
template is tried: |
3251
|
|
|
|
|
|
|
|
3252
|
|
|
|
|
|
|
<package>::<handler_prefix><handler_name> |
3253
|
|
|
|
|
|
|
|
3254
|
|
|
|
|
|
|
If a Handler subroutine is not found by the template search then a check |
3255
|
|
|
|
|
|
|
is made to see if L<handler_name|/handler_name> matches one of |
3256
|
|
|
|
|
|
|
the B<Carp::Proxy> builtin Handlers. The builtin Handlers are surrounded |
3257
|
|
|
|
|
|
|
by C<'*'> characters since those are guaranteed not to collide with user |
3258
|
|
|
|
|
|
|
Handlers. |
3259
|
|
|
|
|
|
|
|
3260
|
|
|
|
|
|
|
*assertion_failure* |
3261
|
|
|
|
|
|
|
*internal_error* |
3262
|
|
|
|
|
|
|
*configuration* |
3263
|
|
|
|
|
|
|
|
3264
|
|
|
|
|
|
|
See L<BUILTIN HANDLERS|/BUILTIN-HANDLERS:> for a description of their |
3265
|
|
|
|
|
|
|
functionality. |
3266
|
|
|
|
|
|
|
|
3267
|
|
|
|
|
|
|
Finally, if a suitable Handler is not found by any of the above searches |
3268
|
|
|
|
|
|
|
the Proxy concludes that you forgot to define a Handler. In response, the |
3269
|
|
|
|
|
|
|
Proxy attempts to shame you into compliance by throwing an exception of |
3270
|
|
|
|
|
|
|
its own: |
3271
|
|
|
|
|
|
|
|
3272
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
3273
|
|
|
|
|
|
|
Oops << embarrassed developers >> |
3274
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
3275
|
|
|
|
|
|
|
*** Description *** |
3276
|
|
|
|
|
|
|
There was an error. The developers caught the error and |
3277
|
|
|
|
|
|
|
attempted to pass diagnosis off to a handler. Unfortunately |
3278
|
|
|
|
|
|
|
they forgot to define the handler. Now there are two |
3279
|
|
|
|
|
|
|
errors. You should complain! |
3280
|
|
|
|
|
|
|
|
3281
|
|
|
|
|
|
|
*** Please contact the maintainer *** |
3282
|
|
|
|
|
|
|
your.name@support.org 555-1212 |
3283
|
|
|
|
|
|
|
|
3284
|
|
|
|
|
|
|
*** Missing Handler *** |
3285
|
|
|
|
|
|
|
handler_name: no_credentials |
3286
|
|
|
|
|
|
|
handler_pkgs: main |
3287
|
|
|
|
|
|
|
handler_prefix: (undef) |
3288
|
|
|
|
|
|
|
|
3289
|
|
|
|
|
|
|
*** Stacktrace *** |
3290
|
|
|
|
|
|
|
fatal called from line 443 of /usr/local/bin/hibs |
3291
|
|
|
|
|
|
|
validate_user called from line 510 of /usr/local/bin/hibs |
3292
|
|
|
|
|
|
|
cmdline called from line 216 of /usr/local/bin/hibs |
3293
|
|
|
|
|
|
|
main called from line 17 of /usr/local/bin/hibs |
3294
|
|
|
|
|
|
|
|
3295
|
|
|
|
|
|
|
=head1 BUILTIN HANDLERS |
3296
|
|
|
|
|
|
|
|
3297
|
|
|
|
|
|
|
These are handler subroutines that come with B<Carp::Proxy>. |
3298
|
|
|
|
|
|
|
|
3299
|
|
|
|
|
|
|
=head2 internal_error |
3300
|
|
|
|
|
|
|
|
3301
|
|
|
|
|
|
|
Usage: |
3302
|
|
|
|
|
|
|
<void> fatal '*internal_error*', @strings; |
3303
|
|
|
|
|
|
|
|
3304
|
|
|
|
|
|
|
The C<'*internal_error*'> Handler can be used to promote warnings to |
3305
|
|
|
|
|
|
|
errors or to turn miscellaneous B<die()> exceptions to full B<Carp::Proxy> |
3306
|
|
|
|
|
|
|
exceptions. The typical use is to trap B<$SIG{__DIE__}> or |
3307
|
|
|
|
|
|
|
B<$SIG{__WARN__}>. |
3308
|
|
|
|
|
|
|
|
3309
|
|
|
|
|
|
|
use English; |
3310
|
|
|
|
|
|
|
|
3311
|
|
|
|
|
|
|
$SIG{__DIE__} = sub{ |
3312
|
|
|
|
|
|
|
|
3313
|
|
|
|
|
|
|
fatal '*internal_error*', @_ |
3314
|
|
|
|
|
|
|
if not $EXCEPTIONS_BEING_CAUGHT; |
3315
|
|
|
|
|
|
|
}; |
3316
|
|
|
|
|
|
|
|
3317
|
|
|
|
|
|
|
A Filled Section is generated from the string interpolation of |
3318
|
|
|
|
|
|
|
I<@strings>. In the above example, the argument is the message that was |
3319
|
|
|
|
|
|
|
passed to B<die()>, like "Illegal division by zero". A |
3320
|
|
|
|
|
|
|
L<contact_maintainer()|/contact_maintainer> Section is also added. |
3321
|
|
|
|
|
|
|
|
3322
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
3323
|
|
|
|
|
|
|
Fatal: << internal error >> |
3324
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
3325
|
|
|
|
|
|
|
*** Description *** |
3326
|
|
|
|
|
|
|
Illegal division by zero at ./combine_decks line 27. |
3327
|
|
|
|
|
|
|
|
3328
|
|
|
|
|
|
|
*** Please contact the maintainer *** |
3329
|
|
|
|
|
|
|
your.name@support.org 555-1212 |
3330
|
|
|
|
|
|
|
|
3331
|
|
|
|
|
|
|
*** Stacktrace *** |
3332
|
|
|
|
|
|
|
... |
3333
|
|
|
|
|
|
|
|
3334
|
|
|
|
|
|
|
=head2 assertion_failure |
3335
|
|
|
|
|
|
|
|
3336
|
|
|
|
|
|
|
Usage: |
3337
|
|
|
|
|
|
|
<void> fatal '*assertion_failure*', $description <, $hashref>; |
3338
|
|
|
|
|
|
|
|
3339
|
|
|
|
|
|
|
If a failing assertion is indicative of a programmer fault then the |
3340
|
|
|
|
|
|
|
primary audience for a diagnostic message will be a maintainer rather than |
3341
|
|
|
|
|
|
|
an end user. Maintainers are most often helped by knowledge of the |
3342
|
|
|
|
|
|
|
surrounding state. The builtin Handler B<*assertion_failure*> attempts to |
3343
|
|
|
|
|
|
|
be a generic Handler, useful for transmitting state to maintainers. |
3344
|
|
|
|
|
|
|
|
3345
|
|
|
|
|
|
|
Using B<*assertion_failure*> frees the programmer from having to write a |
3346
|
|
|
|
|
|
|
Handler. The tradeoff is that some ability to customize the diagnostic is |
3347
|
|
|
|
|
|
|
lost and the invocation syntax is more cluttered. The tradeoff can be |
3348
|
|
|
|
|
|
|
reasonable for events that are rarely triggered, especially if it |
3349
|
|
|
|
|
|
|
encourages programmers to add more assertions. |
3350
|
|
|
|
|
|
|
|
3351
|
|
|
|
|
|
|
B<'*assertion_failure*'> produces a Filled Section with some boilerplate |
3352
|
|
|
|
|
|
|
containing the supplied I<$description>. |
3353
|
|
|
|
|
|
|
|
3354
|
|
|
|
|
|
|
Also included is a Fixed Section which contains a YAML dump of |
3355
|
|
|
|
|
|
|
I<$hashref>. This works best when the HashRef keys act as informational |
3356
|
|
|
|
|
|
|
names (tag=>value pairs) to convey state. YAML is nice here because it |
3357
|
|
|
|
|
|
|
does a great job of serializing complex data structures. |
3358
|
|
|
|
|
|
|
|
3359
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
3360
|
|
|
|
|
|
|
Fatal: << assertion failure >> |
3361
|
|
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
3362
|
|
|
|
|
|
|
*** Description *** |
3363
|
|
|
|
|
|
|
An assertion has failed. This indicates that the internal |
3364
|
|
|
|
|
|
|
state of the program is corrupt. |
3365
|
|
|
|
|
|
|
|
3366
|
|
|
|
|
|
|
<$description> |
3367
|
|
|
|
|
|
|
|
3368
|
|
|
|
|
|
|
*** Please contact the maintainer *** |
3369
|
|
|
|
|
|
|
your.name@support.org 555-1212 |
3370
|
|
|
|
|
|
|
|
3371
|
|
|
|
|
|
|
*** Salient State (YAML) *** |
3372
|
|
|
|
|
|
|
--- |
3373
|
|
|
|
|
|
|
failure: 'unmatched case' |
3374
|
|
|
|
|
|
|
index: 27 |
3375
|
|
|
|
|
|
|
selection: 'brunch' |
3376
|
|
|
|
|
|
|
|
3377
|
|
|
|
|
|
|
*** Stacktrace *** |
3378
|
|
|
|
|
|
|
... |
3379
|
|
|
|
|
|
|
|
3380
|
|
|
|
|
|
|
=head2 configuration |
3381
|
|
|
|
|
|
|
|
3382
|
|
|
|
|
|
|
Usage: |
3383
|
|
|
|
|
|
|
<HashRef> fatal '*configuration*'; |
3384
|
|
|
|
|
|
|
|
3385
|
|
|
|
|
|
|
The C<'*configuration*'> Handler is unconventional in that no exception is |
3386
|
|
|
|
|
|
|
thrown. Instead, a reference to an internal hash is returned to the |
3387
|
|
|
|
|
|
|
calling environment. Any changes to the referenced hash affect all future |
3388
|
|
|
|
|
|
|
Proxy invocations. |
3389
|
|
|
|
|
|
|
|
3390
|
|
|
|
|
|
|
Proxy configuration is established when a Proxy is created - either during |
3391
|
|
|
|
|
|
|
B<use()> or L<import()|/import>. Configuration consists of attribute |
3392
|
|
|
|
|
|
|
=E<gt> parameter pairs that are supplied by the user. |
3393
|
|
|
|
|
|
|
|
3394
|
|
|
|
|
|
|
use Carp::Proxy ( warning => { banner_title => 'Warning', |
3395
|
|
|
|
|
|
|
disposition => 'warn' }); |
3396
|
|
|
|
|
|
|
|
3397
|
|
|
|
|
|
|
In the above snippet, L<banner_title|/banner_title> and |
3398
|
|
|
|
|
|
|
L<disposition|/disposition>, are internally held in a |
3399
|
|
|
|
|
|
|
closure-based hash that persists across all invocations of the Proxy. The |
3400
|
|
|
|
|
|
|
B<*configuration*> Handler causes the Proxy to return a reference to this |
3401
|
|
|
|
|
|
|
internal hash. |
3402
|
|
|
|
|
|
|
|
3403
|
|
|
|
|
|
|
Here is an example of wanting to change Proxy behavior after Proxy |
3404
|
|
|
|
|
|
|
creation: |
3405
|
|
|
|
|
|
|
|
3406
|
|
|
|
|
|
|
#----- fatal() does NOT throw an exception here... |
3407
|
|
|
|
|
|
|
my $config = fatal '*configuration*'; |
3408
|
|
|
|
|
|
|
|
3409
|
|
|
|
|
|
|
$config->{ disposition } = \&GUI::as_dialog; |
3410
|
|
|
|
|
|
|
|
3411
|
|
|
|
|
|
|
As alluded to above, we want our GUI program to use conventional STDERR |
3412
|
|
|
|
|
|
|
based messages during initialization, but once the GUI is up we want |
3413
|
|
|
|
|
|
|
future messages to go to a dialog widget. |
3414
|
|
|
|
|
|
|
|
3415
|
|
|
|
|
|
|
=head1 BUGS AND LIMITATIONS |
3416
|
|
|
|
|
|
|
|
3417
|
|
|
|
|
|
|
Please report any bugs or feature requests to C<bug-carp-proxy at |
3418
|
|
|
|
|
|
|
rt.cpan.org>, or through the web interface at |
3419
|
|
|
|
|
|
|
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Carp-Proxy>. I will be |
3420
|
|
|
|
|
|
|
notified, and then you'll automatically be notified of progress on your |
3421
|
|
|
|
|
|
|
bug as I make changes. |
3422
|
|
|
|
|
|
|
|
3423
|
|
|
|
|
|
|
=head1 DEPENDENCIES |
3424
|
|
|
|
|
|
|
|
3425
|
|
|
|
|
|
|
Core dependencies (come with Perl) |
3426
|
|
|
|
|
|
|
|
3427
|
|
|
|
|
|
|
Config |
3428
|
|
|
|
|
|
|
Cwd |
3429
|
|
|
|
|
|
|
English |
3430
|
|
|
|
|
|
|
overload |
3431
|
|
|
|
|
|
|
Pod::Usage |
3432
|
|
|
|
|
|
|
|
3433
|
|
|
|
|
|
|
External dependencies (install from CPAN) |
3434
|
|
|
|
|
|
|
|
3435
|
|
|
|
|
|
|
Moose |
3436
|
|
|
|
|
|
|
Readonly |
3437
|
|
|
|
|
|
|
Sub::Name |
3438
|
|
|
|
|
|
|
YAML::XS |
3439
|
|
|
|
|
|
|
|
3440
|
|
|
|
|
|
|
=head1 SUPPORT |
3441
|
|
|
|
|
|
|
|
3442
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
3443
|
|
|
|
|
|
|
|
3444
|
|
|
|
|
|
|
perldoc Carp::Proxy |
3445
|
|
|
|
|
|
|
|
3446
|
|
|
|
|
|
|
|
3447
|
|
|
|
|
|
|
You can also look for information at: |
3448
|
|
|
|
|
|
|
|
3449
|
|
|
|
|
|
|
=over 4 |
3450
|
|
|
|
|
|
|
|
3451
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker (report bugs here) |
3452
|
|
|
|
|
|
|
|
3453
|
|
|
|
|
|
|
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Carp-Proxy> |
3454
|
|
|
|
|
|
|
|
3455
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
3456
|
|
|
|
|
|
|
|
3457
|
|
|
|
|
|
|
L<http://annocpan.org/dist/Carp-Proxy> |
3458
|
|
|
|
|
|
|
|
3459
|
|
|
|
|
|
|
=item * CPAN Ratings |
3460
|
|
|
|
|
|
|
|
3461
|
|
|
|
|
|
|
L<http://cpanratings.perl.org/d/Carp-Proxy> |
3462
|
|
|
|
|
|
|
|
3463
|
|
|
|
|
|
|
=item * Search CPAN |
3464
|
|
|
|
|
|
|
|
3465
|
|
|
|
|
|
|
L<http://search.cpan.org/dist/Carp-Proxy/> |
3466
|
|
|
|
|
|
|
|
3467
|
|
|
|
|
|
|
=back |
3468
|
|
|
|
|
|
|
|
3469
|
|
|
|
|
|
|
|
3470
|
|
|
|
|
|
|
=head1 SEE ALSO |
3471
|
|
|
|
|
|
|
|
3472
|
|
|
|
|
|
|
=over 4 |
3473
|
|
|
|
|
|
|
|
3474
|
|
|
|
|
|
|
=item perldoc L<perlvar> |
3475
|
|
|
|
|
|
|
|
3476
|
|
|
|
|
|
|
The section on $CHILD_ERROR describes information packing when a child |
3477
|
|
|
|
|
|
|
process terminates. This is used by |
3478
|
|
|
|
|
|
|
L<decipher_child_error()|/decipher_child_error>. |
3479
|
|
|
|
|
|
|
|
3480
|
|
|
|
|
|
|
=item perldoc -f die |
3481
|
|
|
|
|
|
|
|
3482
|
|
|
|
|
|
|
The documentation on Perl's B<die()> details how the exit code for a process |
3483
|
|
|
|
|
|
|
depends on B<$ERRNO> and B<$CHILD_ERROR>. |
3484
|
|
|
|
|
|
|
|
3485
|
|
|
|
|
|
|
=item perldoc L<Pod::Usage> |
3486
|
|
|
|
|
|
|
|
3487
|
|
|
|
|
|
|
The L<synopsis()|/synopsis> method calls B<pod2usage()> to format |
3488
|
|
|
|
|
|
|
the B<SYNOPSIS> section from user POD. |
3489
|
|
|
|
|
|
|
|
3490
|
|
|
|
|
|
|
=item perldoc L<YAML::XS> |
3491
|
|
|
|
|
|
|
|
3492
|
|
|
|
|
|
|
The L<as_yaml|/as_yaml> attribute produces a YAML Dump of the |
3493
|
|
|
|
|
|
|
B<Carp::Proxy> object so that it can be reconstituted later. |
3494
|
|
|
|
|
|
|
|
3495
|
|
|
|
|
|
|
The L<*assertion_failure*|/assertion_failure> builtin |
3496
|
|
|
|
|
|
|
Handler produces a Section containing YAML Dump of a user HashRef. |
3497
|
|
|
|
|
|
|
|
3498
|
|
|
|
|
|
|
=item perldoc L<Carp> |
3499
|
|
|
|
|
|
|
|
3500
|
|
|
|
|
|
|
The 'croak' and 'confess' concepts were originated by B<Carp>. If you are |
3501
|
|
|
|
|
|
|
making a Do-it-yourself CodeRef for L<context|/context> then |
3502
|
|
|
|
|
|
|
B<Carp>'s B<longmess()> or B<longmess_heavy()> may prove useful. |
3503
|
|
|
|
|
|
|
|
3504
|
|
|
|
|
|
|
=back |
3505
|
|
|
|
|
|
|
|
3506
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
3507
|
|
|
|
|
|
|
|
3508
|
|
|
|
|
|
|
Copyright 2014-2015 Paul Liebert. |
3509
|
|
|
|
|
|
|
|
3510
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
3511
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
3512
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
3513
|
|
|
|
|
|
|
|
3514
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
3515
|
|
|
|
|
|
|
|
3516
|
|
|
|
|
|
|
=cut |