line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# A base class supplying error, warning, status, and debug facilities. |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package UR::ModuleBase; |
4
|
|
|
|
|
|
|
|
5
|
266
|
|
|
266
|
|
108325
|
use Sub::Name; |
|
266
|
|
|
|
|
127356
|
|
|
266
|
|
|
|
|
12388
|
|
6
|
266
|
|
|
266
|
|
103490
|
use Sub::Install; |
|
266
|
|
|
|
|
334091
|
|
|
266
|
|
|
|
|
923
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
BEGIN { |
9
|
266
|
|
|
266
|
|
7968
|
use Class::Autouse; |
|
266
|
|
|
|
|
347
|
|
|
266
|
|
|
|
|
2537
|
|
10
|
|
|
|
|
|
|
# the file above now does this, but just in case: |
11
|
|
|
|
|
|
|
# subsequent uses of this module w/o the special override should just do nothing... |
12
|
266
|
|
|
266
|
|
541
|
$INC{"Class/Autouse_1_99_02.pm"} = 1; |
13
|
266
|
|
|
|
|
454
|
$INC{"Class/Autouse_1_99_04.pm"} = 1; |
14
|
266
|
|
|
266
|
|
9694
|
no strict; |
|
266
|
|
|
|
|
332
|
|
|
266
|
|
|
|
|
4560
|
|
15
|
266
|
|
|
266
|
|
849
|
no warnings; |
|
266
|
|
|
|
|
285
|
|
|
266
|
|
|
|
|
11046
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# ensure that modules which inherit from this never fall into the |
18
|
|
|
|
|
|
|
# replaced UNIVERSAL::can/isa |
19
|
266
|
|
|
|
|
702
|
*can = $Class::Autouse::ORIGINAL_CAN; |
20
|
266
|
|
|
|
|
5952
|
*isa = $Class::Autouse::ORIGINAL_ISA; |
21
|
|
|
|
|
|
|
} |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=pod |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 NAME |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
UR::ModuleBase - Methods common to all UR classes and object instances. |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 DESCRIPTION |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
This is a base class for packages, classes, and objects which need to |
32
|
|
|
|
|
|
|
manage basic functionality in the UR framework such as inheritance, |
33
|
|
|
|
|
|
|
AUTOLOAD/AUTOSUB methods, error/status/warning/etc messages. |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
UR::ModuleBase is in the @ISA list for UR::Object, but UR::ModuleBase is not |
36
|
|
|
|
|
|
|
a formal UR class. |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
=head1 METHODS |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=cut |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# set up package |
43
|
|
|
|
|
|
|
require 5.006_000; |
44
|
266
|
|
|
266
|
|
954
|
use warnings; |
|
266
|
|
|
|
|
285
|
|
|
266
|
|
|
|
|
4786
|
|
45
|
266
|
|
|
266
|
|
782
|
use strict; |
|
266
|
|
|
|
|
300
|
|
|
266
|
|
|
|
|
6895
|
|
46
|
|
|
|
|
|
|
our $VERSION = "0.46"; # UR $VERSION;; |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
# set up module |
49
|
266
|
|
|
266
|
|
834
|
use Carp; |
|
266
|
|
|
|
|
312
|
|
|
266
|
|
|
|
|
11152
|
|
50
|
266
|
|
|
266
|
|
126687
|
use IO::Handle; |
|
266
|
|
|
|
|
1211935
|
|
|
266
|
|
|
|
|
9797
|
|
51
|
266
|
|
|
266
|
|
1376
|
use UR::Util; |
|
266
|
|
|
|
|
330
|
|
|
266
|
|
|
|
|
2343
|
|
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=pod |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=over |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=item C |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
$class = $obj->class; |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
This returns the class name of a class or an object as a string. |
62
|
|
|
|
|
|
|
It is exactly equivalent to: |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
(ref($self) ? ref($self) : $self) |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=cut |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
sub class |
69
|
|
|
|
|
|
|
{ |
70
|
643
|
|
|
643
|
1
|
584
|
my $class = shift; |
71
|
643
|
50
|
|
|
|
1120
|
$class = ref($class) if ref($class); |
72
|
643
|
|
|
|
|
1301
|
return $class; |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=pod |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=item C |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
$sub_ref = $obj->super_can('func'); |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
This method determines if any of the super classes of the C<$obj> |
82
|
|
|
|
|
|
|
object can perform the method C. If any one of them can, |
83
|
|
|
|
|
|
|
reference to the subroutine that would be called (determined using a |
84
|
|
|
|
|
|
|
depth-first search of the C<@ISA> array) is returned. If none of the |
85
|
|
|
|
|
|
|
super classes provide a method named C, C is returned. |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=cut |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub super_can |
90
|
|
|
|
|
|
|
{ |
91
|
34
|
|
|
34
|
1
|
149
|
my $class = shift; |
92
|
|
|
|
|
|
|
|
93
|
34
|
|
|
|
|
131
|
foreach my $parent_class ( $class->parent_classes ) |
94
|
|
|
|
|
|
|
{ |
95
|
36
|
|
|
|
|
164
|
my $code = $parent_class->can(@_); |
96
|
36
|
100
|
|
|
|
366
|
return $code if $code; |
97
|
|
|
|
|
|
|
} |
98
|
0
|
|
|
|
|
0
|
return; |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=pod |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
=item C |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
@classes = $obj->inheritance; |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
This method returns a depth-first list of all the classes (packages) |
108
|
|
|
|
|
|
|
that the class that C<$obj> was blessed into inherits from. This |
109
|
|
|
|
|
|
|
order is the same order as is searched when searching for inherited |
110
|
|
|
|
|
|
|
methods to execute. If the class has no super classes, an empty list |
111
|
|
|
|
|
|
|
is returned. The C class is not returned unless explicitly |
112
|
|
|
|
|
|
|
put into the C<@ISA> array by the class or one of its super classes. |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=cut |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub inheritance { |
117
|
347734
|
|
|
347734
|
1
|
269052
|
my $self = $_[0]; |
118
|
347734
|
|
66
|
|
|
767030
|
my $class = ref($self) || $self; |
119
|
347734
|
100
|
|
|
|
395567
|
return unless $class; |
120
|
266
|
|
|
266
|
|
30400
|
no strict; |
|
266
|
|
|
|
|
372
|
|
|
266
|
|
|
|
|
24095
|
|
121
|
347733
|
|
|
|
|
215677
|
my @parent_classes = @{$class . '::ISA'}; |
|
347733
|
|
|
|
|
839463
|
|
122
|
|
|
|
|
|
|
|
123
|
347733
|
|
|
|
|
219198
|
my @ordered_inheritance; |
124
|
347733
|
|
|
|
|
294217
|
foreach my $parent_class (@parent_classes) { |
125
|
270807
|
50
|
|
|
|
430740
|
push @ordered_inheritance, $parent_class, ($parent_class eq 'UR' ? () : inheritance($parent_class) ); |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
347733
|
|
|
|
|
639948
|
return @ordered_inheritance; |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=pod |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=item C |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
MyClass->parent_classes; |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
This returns the immediate parent class, or parent classes in the case |
138
|
|
|
|
|
|
|
of multiple inheritance. In no case does it follow the inheritance |
139
|
|
|
|
|
|
|
hierarchy as ->inheritance() does. |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=cut |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
sub parent_classes |
144
|
|
|
|
|
|
|
{ |
145
|
41
|
|
|
41
|
1
|
48
|
my $self = $_[0]; |
146
|
41
|
|
66
|
|
|
213
|
my $class = ref($self) || $self; |
147
|
266
|
|
|
266
|
|
1037
|
no strict 'refs'; |
|
266
|
|
|
|
|
354
|
|
|
266
|
|
|
|
|
47944
|
|
148
|
41
|
|
|
|
|
49
|
my @parent_classes = @{$class . '::ISA'}; |
|
41
|
|
|
|
|
188
|
|
149
|
41
|
50
|
|
|
|
126
|
return (wantarray ? @parent_classes : $parent_classes[0]); |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=pod |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=item C |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
MyModule->base_dir; |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
This returns the base directory for a given module, in which the modules's |
159
|
|
|
|
|
|
|
supplemental data will be stored, such as config files and glade files, |
160
|
|
|
|
|
|
|
data caches, etc. |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
It uses %INC. |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=cut |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub base_dir |
167
|
|
|
|
|
|
|
{ |
168
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
169
|
0
|
|
0
|
|
|
0
|
my $class = ref($self) || $self; |
170
|
0
|
|
|
|
|
0
|
$class =~ s/\:\:/\//g; |
171
|
0
|
|
0
|
|
|
0
|
my $dir = $INC{$class . '.pm'} || $INC{$class . '.pl'}; |
172
|
0
|
0
|
|
|
|
0
|
die "Failed to find module $class in \%INC: " . Data::Dumper(%INC) unless ($dir); |
173
|
0
|
|
|
|
|
0
|
$dir =~ s/\.p[lm]\s*$//; |
174
|
0
|
|
|
|
|
0
|
return $dir; |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=pod |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=item methods |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
Undocumented. |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=cut |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub methods |
186
|
|
|
|
|
|
|
{ |
187
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
188
|
0
|
|
|
|
|
0
|
my @methods; |
189
|
|
|
|
|
|
|
my %methods; |
190
|
0
|
|
|
|
|
0
|
my ($class, $possible_method, $possible_method_full, $r, $r1, $r2); |
191
|
266
|
|
|
266
|
|
1250
|
no strict; |
|
266
|
|
|
|
|
313
|
|
|
266
|
|
|
|
|
5119
|
|
192
|
266
|
|
|
266
|
|
1155
|
no warnings; |
|
266
|
|
|
|
|
319
|
|
|
266
|
|
|
|
|
84203
|
|
193
|
|
|
|
|
|
|
|
194
|
0
|
|
|
|
|
0
|
for $class (reverse($self, $self->inheritance())) |
195
|
|
|
|
|
|
|
{ |
196
|
0
|
|
|
|
|
0
|
print "$class\n"; |
197
|
0
|
|
|
|
|
0
|
for $possible_method (sort grep { not /^_/ } keys %{$class . "::"}) |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
198
|
|
|
|
|
|
|
{ |
199
|
0
|
|
|
|
|
0
|
$possible_method_full = $class . "::" . $possible_method; |
200
|
|
|
|
|
|
|
|
201
|
0
|
|
|
|
|
0
|
$r1 = $class->can($possible_method); |
202
|
0
|
0
|
|
|
|
0
|
next unless $r1; # not implemented |
203
|
|
|
|
|
|
|
|
204
|
0
|
|
|
|
|
0
|
$r2 = $class->super_can($possible_method); |
205
|
0
|
0
|
|
|
|
0
|
next if $r2 eq $r1; # just inherited |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
{ |
208
|
0
|
|
|
|
|
0
|
push @methods, $possible_method_full; |
|
0
|
|
|
|
|
0
|
|
209
|
0
|
|
|
|
|
0
|
push @{ $methods{$possible_method} }, $class; |
|
0
|
|
|
|
|
0
|
|
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
} |
213
|
0
|
|
|
|
|
0
|
print Dumper(\%methods); |
214
|
0
|
|
|
|
|
0
|
return @methods; |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=pod |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=item C |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
return MyClass->context_return(@return_values); |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
Attempts to return either an array or scalar based on the calling context. |
224
|
|
|
|
|
|
|
Will die if called in scalar context and @return_values has more than 1 |
225
|
|
|
|
|
|
|
element. |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=cut |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
sub context_return { |
230
|
867080
|
|
|
867080
|
1
|
633522
|
my $class = shift; |
231
|
867080
|
100
|
|
|
|
1164740
|
return unless defined wantarray; |
232
|
867075
|
100
|
|
|
|
1054025
|
return @_ if wantarray; |
233
|
859761
|
100
|
|
|
|
1062534
|
if (@_ > 1) { |
234
|
1
|
|
|
|
|
11
|
my @caller = caller(1); |
235
|
1
|
|
|
|
|
255
|
Carp::croak("Method $caller[3] on $class called in scalar context, but " . scalar(@_) . " items need to be returned"); |
236
|
|
|
|
|
|
|
} |
237
|
859760
|
|
|
|
|
2942315
|
return $_[0]; |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
=pod |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
=back |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
=head1 C |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
This package implements AUTOLOAD so that derived classes can use |
247
|
|
|
|
|
|
|
AUTOSUB instead of AUTOLOAD. |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
When a class or object has a method called which is not found in the |
250
|
|
|
|
|
|
|
final class or any derived classes, perl checks up the tree for |
251
|
|
|
|
|
|
|
AUTOLOAD. We implement AUTOLOAD at the top of the tree, and then |
252
|
|
|
|
|
|
|
check each class in the tree in order for an AUTOSUB method. Where a |
253
|
|
|
|
|
|
|
class implements AUTOSUB, it will receive a function name as its first |
254
|
|
|
|
|
|
|
parameter, and it is expected to return either a subroutine reference, |
255
|
|
|
|
|
|
|
or undef. If undef is returned then the inheritance tree search will |
256
|
|
|
|
|
|
|
continue. If a subroutine reference is returned it will be executed |
257
|
|
|
|
|
|
|
immediately with the @_ passed into AUTOLOAD. Typically, AUTOSUB will |
258
|
|
|
|
|
|
|
be used to generate a subroutine reference, and will then associate |
259
|
|
|
|
|
|
|
the subref with the function name to avoid repeated calls to AUTOLOAD |
260
|
|
|
|
|
|
|
and AUTOSUB. |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
Why not use AUTOLOAD directly in place of AUTOSUB? |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
On an object with a complex inheritance tree, AUTOLOAD is only found |
265
|
|
|
|
|
|
|
once, after which, there is no way to indicate that the given AUTOLOAD |
266
|
|
|
|
|
|
|
has failed and that the inheritance tree trek should continue for |
267
|
|
|
|
|
|
|
other AUTOLOADS which might implement the given method. |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
Example: |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
package MyClass; |
272
|
|
|
|
|
|
|
our @ISA = ('UR'); |
273
|
|
|
|
|
|
|
##- use UR; |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub AUTOSUB |
276
|
|
|
|
|
|
|
{ |
277
|
|
|
|
|
|
|
my $sub_name = shift; |
278
|
|
|
|
|
|
|
if ($sub_name eq 'foo') |
279
|
|
|
|
|
|
|
{ |
280
|
|
|
|
|
|
|
*MyClass::foo = sub { print "Calling MyClass::foo()\n" }; |
281
|
|
|
|
|
|
|
return \&MyClass::foo; |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
elsif ($sub_name eq 'bar') |
284
|
|
|
|
|
|
|
{ |
285
|
|
|
|
|
|
|
*MyClass::bar = sub { print "Calling MyClass::bar()\n" }; |
286
|
|
|
|
|
|
|
return \&MyClass::bar; |
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
else |
289
|
|
|
|
|
|
|
{ |
290
|
|
|
|
|
|
|
return; |
291
|
|
|
|
|
|
|
} |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
package MySubClass; |
295
|
|
|
|
|
|
|
our @ISA = ('MyClass'); |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
sub AUTOSUB |
298
|
|
|
|
|
|
|
{ |
299
|
|
|
|
|
|
|
my $sub_name = shift; |
300
|
|
|
|
|
|
|
if ($sub_name eq 'baz') |
301
|
|
|
|
|
|
|
{ |
302
|
|
|
|
|
|
|
*MyClass::baz = sub { print "Calling MyClass::baz()\n" }; |
303
|
|
|
|
|
|
|
return \&MyClass::baz; |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
else |
306
|
|
|
|
|
|
|
{ |
307
|
|
|
|
|
|
|
return; |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
package main; |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
my $obj = bless({},'MySubClass'); |
314
|
|
|
|
|
|
|
$obj->foo; |
315
|
|
|
|
|
|
|
$obj->bar; |
316
|
|
|
|
|
|
|
$obj->baz; |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=cut |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
our $AUTOLOAD; |
321
|
|
|
|
|
|
|
sub AUTOLOAD { |
322
|
|
|
|
|
|
|
|
323
|
5
|
|
|
5
|
|
8
|
my $self = $_[0]; |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# The debugger can't see $AUTOLOAD. This is just here for debugging. |
326
|
5
|
|
|
|
|
7
|
my $autoload = $AUTOLOAD; |
327
|
|
|
|
|
|
|
|
328
|
5
|
|
|
|
|
28
|
$autoload =~ /(.*)::([^\:]+)$/; |
329
|
5
|
|
|
|
|
15
|
my $package = $1; |
330
|
5
|
|
|
|
|
9
|
my $function = $2; |
331
|
|
|
|
|
|
|
|
332
|
5
|
50
|
|
|
|
18
|
return if $function eq 'DESTROY'; |
333
|
|
|
|
|
|
|
|
334
|
5
|
50
|
|
|
|
12
|
unless ($package) { |
335
|
0
|
|
|
|
|
0
|
Carp::confess("Failed to determine package name from autoload string $autoload"); |
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
# switch these to use Class::AutoCAN / CAN? |
339
|
266
|
|
|
266
|
|
1180
|
no strict; |
|
266
|
|
|
|
|
305
|
|
|
266
|
|
|
|
|
5465
|
|
340
|
266
|
|
|
266
|
|
831
|
no warnings; |
|
266
|
|
|
|
|
341
|
|
|
266
|
|
|
|
|
436473
|
|
341
|
5
|
|
|
|
|
23
|
my @classes = grep {$_} ($self, inheritance($self) ); |
|
5
|
|
|
|
|
15
|
|
342
|
5
|
|
|
|
|
14
|
for my $class (@classes) { |
343
|
4
|
50
|
|
|
|
21
|
if (my $AUTOSUB = $class->can("AUTOSUB")) |
344
|
|
|
|
|
|
|
# FIXME The above causes hard-to-read error messages if $class isn't really a class or object ref |
345
|
|
|
|
|
|
|
# The 2 lines below should fix the problem, but instead make other more impoartant things not work |
346
|
|
|
|
|
|
|
#my $AUTOSUB = eval { $class->can('AUTOSUB') }; |
347
|
|
|
|
|
|
|
#if ($AUTOSUB) { |
348
|
|
|
|
|
|
|
{ |
349
|
0
|
0
|
|
|
|
0
|
if (my $subref = $AUTOSUB->($function,@_)) { |
350
|
0
|
|
|
|
|
0
|
goto $subref; |
351
|
|
|
|
|
|
|
} |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
|
355
|
5
|
50
|
33
|
|
|
226
|
if ($autoload and $autoload !~ /::DESTROY$/) { |
356
|
5
|
|
|
|
|
10
|
my $subref = \&Carp::confess; |
357
|
5
|
|
|
|
|
22
|
@_ = ("Can't locate object method \"$function\" via package \"$package\" (perhaps you forgot to load \"$package\"?)"); |
358
|
5
|
|
|
|
|
995
|
goto $subref; |
359
|
|
|
|
|
|
|
} |
360
|
|
|
|
|
|
|
} |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
=pod |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
=head1 MESSAGING |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
UR::ModuleBase implements several methods for sending and storing error, warning and |
368
|
|
|
|
|
|
|
status messages to the user. |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
# common usage |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
sub foo { |
373
|
|
|
|
|
|
|
my $self = shift; |
374
|
|
|
|
|
|
|
... |
375
|
|
|
|
|
|
|
if ($problem) { |
376
|
|
|
|
|
|
|
$self->error_message("Something went wrong..."); |
377
|
|
|
|
|
|
|
return; |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
return 1; |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
unless ($obj->foo) { |
383
|
|
|
|
|
|
|
print LOG $obj->error_message(); |
384
|
|
|
|
|
|
|
} |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
=head2 Messaging Methods |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=over 4 |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
=item message_types |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
@types = UR::ModuleBase->message_types; |
393
|
|
|
|
|
|
|
UR::ModuleBase->message_types(@more_types); |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
With no arguments, this method returns all the types of messages that |
396
|
|
|
|
|
|
|
this class handles. With arguments, it adds a new type to the |
397
|
|
|
|
|
|
|
list. |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
Standard message types are fatal, error, status, warning, debug and usage. |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
Note that the addition of new types is not fully supported/implemented |
402
|
|
|
|
|
|
|
yet. |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
=back |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
=cut |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
my $create_subs_for_message_type; # filled in lower down |
409
|
|
|
|
|
|
|
my @message_types = qw(error status warning debug usage fatal); |
410
|
|
|
|
|
|
|
sub message_types |
411
|
|
|
|
|
|
|
{ |
412
|
266
|
|
|
266
|
1
|
6115
|
my $self = shift; |
413
|
266
|
50
|
|
|
|
5941
|
if (@_) |
414
|
|
|
|
|
|
|
{ |
415
|
0
|
|
|
|
|
0
|
foreach my $msg_type ( @_ ) { |
416
|
0
|
0
|
|
|
|
0
|
if (! $self->can("${msg_type}_message")) { |
417
|
|
|
|
|
|
|
# This is a new one |
418
|
0
|
|
|
|
|
0
|
$create_subs_for_message_type->($self, $msg_type); |
419
|
0
|
|
|
|
|
0
|
push @message_types, $msg_type; |
420
|
|
|
|
|
|
|
} |
421
|
|
|
|
|
|
|
} |
422
|
|
|
|
|
|
|
} else { |
423
|
266
|
|
|
|
|
2799
|
return grep { $self->can($_ . '_message') } @message_types; |
|
1596
|
|
|
|
|
8967
|
|
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
} |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
# Most defaults are false |
429
|
|
|
|
|
|
|
my %default_messaging_settings; |
430
|
|
|
|
|
|
|
$default_messaging_settings{dump_error_messages} = 1; |
431
|
|
|
|
|
|
|
$default_messaging_settings{dump_warning_messages} = 1; |
432
|
|
|
|
|
|
|
$default_messaging_settings{dump_status_messages} = 1; |
433
|
|
|
|
|
|
|
$default_messaging_settings{dump_fatal_messages} = 1; |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
# |
436
|
|
|
|
|
|
|
# Implement error_mesage/warning_message/status_message in a way |
437
|
|
|
|
|
|
|
# which handles object-specific callbacks. |
438
|
|
|
|
|
|
|
# |
439
|
|
|
|
|
|
|
# Build a set of methods for getting/setting/printing error/warning/status messages |
440
|
|
|
|
|
|
|
# $class->dump_error_messages() Turn on/off printing the messages to STDERR |
441
|
|
|
|
|
|
|
# error and warnings default to on, status messages default to off |
442
|
|
|
|
|
|
|
# $class->queue_error_messages() Turn on/off queueing of messages |
443
|
|
|
|
|
|
|
# defaults to off |
444
|
|
|
|
|
|
|
# $class->error_message("blah"): set an error message |
445
|
|
|
|
|
|
|
# $class->error_message() return the last message |
446
|
|
|
|
|
|
|
# $class->error_messages() return all the messages that have been queued up |
447
|
|
|
|
|
|
|
# $class->error_messages_arrayref() return the reference to the underlying |
448
|
|
|
|
|
|
|
# list messages get queued to. This is the method for truncating the list |
449
|
|
|
|
|
|
|
# or altering already queued messages |
450
|
|
|
|
|
|
|
# $class->error_messages_callback() Specify a callback for when error |
451
|
|
|
|
|
|
|
# messages are set. The callback runs before printing or queueing, so |
452
|
|
|
|
|
|
|
# you can alter @_ and change the message that gets printed or queued |
453
|
|
|
|
|
|
|
# And then the same thing for status and warning messages |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
=pod |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
For each message type, several methods are created for sending and retrieving messages, |
458
|
|
|
|
|
|
|
registering a callback to run when messages are sent, controlling whether the messages |
459
|
|
|
|
|
|
|
are printed on the terminal, and whether the messages are queued up. |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
For example, for the "error" message type, these methods are created: |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
=over 4 |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
=item error_message |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
$obj->error_message("Something went wrong..."); |
468
|
|
|
|
|
|
|
$obj->error_message($format, @list); |
469
|
|
|
|
|
|
|
$msg = $obj->error_message(); |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
When called with one or more arguments, it sends an error message to the |
472
|
|
|
|
|
|
|
object. The error_message_callback will be run, if one is registered, and the |
473
|
|
|
|
|
|
|
message will be printed to the terminal. When given a single argument, it will |
474
|
|
|
|
|
|
|
be passed through unmodified. When given multiple arguments, error_message will |
475
|
|
|
|
|
|
|
assume the first is a format string and the remainder are parameters to |
476
|
|
|
|
|
|
|
sprintf. When called with no arguments, the last message sent will be |
477
|
|
|
|
|
|
|
returned. If the message is C then no message is printed or queued, and |
478
|
|
|
|
|
|
|
the next time error_message is run as an accessor, it will return |
479
|
|
|
|
|
|
|
undef. |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
Note that C will throw an exception at the point it appears |
482
|
|
|
|
|
|
|
in the program. This exception, like others, is trappable bi C. |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
=item dump_error_messages |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
$obj->dump_error_messages(0); |
487
|
|
|
|
|
|
|
$flag = $obj->dump_error_messages(); |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
Get or set the flag which controls whether messages sent via C |
490
|
|
|
|
|
|
|
is printed to the terminal. This flag defaults to true for warning and error |
491
|
|
|
|
|
|
|
messages, and false for others. |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
Note that C messages and exceptions do not honor the value of |
494
|
|
|
|
|
|
|
C, and always print their message and throw their |
495
|
|
|
|
|
|
|
exception unless trapped with an C. |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
=item queue_error_messages |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
$obj->queue_error_messages(0); |
500
|
|
|
|
|
|
|
$flag = $obj->queue_error_messages(); |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
Get or set the flag which control whether messages send via C |
503
|
|
|
|
|
|
|
are saved into a list. If true, every message sent is saved and can be retrieved |
504
|
|
|
|
|
|
|
with L or L. This flag defaults to |
505
|
|
|
|
|
|
|
false for all message types. |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
=item error_messages_callback |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
$obj->error_messages_callback($subref); |
510
|
|
|
|
|
|
|
$subref = $obj->error_messages_callback(); |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
Get or set the callback run whenever an error_message is sent. This callback |
513
|
|
|
|
|
|
|
is run with two arguments: The object or class error_message() was called on, |
514
|
|
|
|
|
|
|
and a string containing the message. This callback is run before the message |
515
|
|
|
|
|
|
|
is printed to the terminal or queued into its list. The callback can modify |
516
|
|
|
|
|
|
|
the message (by writing to $_[1]) and affect the message that is printed or |
517
|
|
|
|
|
|
|
queued. If $_[1] is set to C, then no message is printed or queued, |
518
|
|
|
|
|
|
|
and the last recorded message is set to undef as when calling error_message |
519
|
|
|
|
|
|
|
with undef as the argument. |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
=item error_messages |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
@list = $obj->error_messages(); |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
If the queue_error_messages flag is on, then this method returns the entire list |
526
|
|
|
|
|
|
|
of queued messages. |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
When called as an instance method, it returns the errors queued only on that |
529
|
|
|
|
|
|
|
object. When called as a class method, it returns the errors queued on that |
530
|
|
|
|
|
|
|
class, all it's subclasses, and all instances of that class or subclasses. |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
=item error_messages_arrayref |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
$listref = $obj->error_messages_arrayref(); |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
If the queue_error_messages flag is on, then this method returns a reference to |
537
|
|
|
|
|
|
|
the actual list where messages get queued. This list can be manipulated to add |
538
|
|
|
|
|
|
|
or remove items. |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
=item error_message_source |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
%source_info = $obj->error_message_source |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
Returns a hash of information about the most recent call to error_message. |
545
|
|
|
|
|
|
|
The key "error_message" contains the message. The keys error_package, |
546
|
|
|
|
|
|
|
error_file, error_line and error_subroutine contain info about the location |
547
|
|
|
|
|
|
|
in the code where error_message() was called. |
548
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
=item error_package |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
=item error_file |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
=item error_line |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
=item error_subroutine |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
These methods return the same data as $obj->error_message_source(). |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
=back |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
=cut |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
our $stderr = \*STDERR; |
564
|
|
|
|
|
|
|
our $stdout = \*STDOUT; |
565
|
|
|
|
|
|
|
my %message_settings; |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
# This sub creates the settings mutator subs for each message type |
568
|
|
|
|
|
|
|
# For example, when passed in 'error', it creates the subs error_messages_callback, |
569
|
|
|
|
|
|
|
# queue_error_messages, dump_error_messages, etc |
570
|
|
|
|
|
|
|
$create_subs_for_message_type = sub { |
571
|
|
|
|
|
|
|
my($self, $type) = @_; |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
my $class = ref($self) ? $self->class : $self; |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
my $save_setting = sub { |
576
|
|
|
|
|
|
|
my($self, $name, $val) = @_; |
577
|
|
|
|
|
|
|
if (ref $self) { |
578
|
|
|
|
|
|
|
$message_settings{ $self->class . '::' . $name . '_by_id' }->{$self->id} = $val; |
579
|
|
|
|
|
|
|
} else { |
580
|
|
|
|
|
|
|
$message_settings{ $self->class . '::' . $name } = $val; |
581
|
|
|
|
|
|
|
} |
582
|
|
|
|
|
|
|
}; |
583
|
|
|
|
|
|
|
my $get_setting = sub { |
584
|
|
|
|
|
|
|
my($self, $name) = @_; |
585
|
|
|
|
|
|
|
if (ref $self) { |
586
|
|
|
|
|
|
|
return exists($message_settings{ $self->class . '::' . $name . '_by_id' }) |
587
|
|
|
|
|
|
|
? $message_settings{ $self->class . '::' . $name . '_by_id' }->{$self->id} |
588
|
|
|
|
|
|
|
: undef; |
589
|
|
|
|
|
|
|
} else { |
590
|
|
|
|
|
|
|
return $message_settings{ $self->class . '::' . $name }; |
591
|
|
|
|
|
|
|
} |
592
|
|
|
|
|
|
|
}; |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
my $make_mutator = sub { |
595
|
|
|
|
|
|
|
my $name = shift; |
596
|
|
|
|
|
|
|
return sub { |
597
|
6044
|
|
|
6044
|
|
31225
|
my $self = shift; |
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
|
|
|
|
6044
|
|
|
|
598
|
|
|
|
|
|
|
|
599
|
6044
|
100
|
|
|
|
7887
|
if (@_) { |
600
|
|
|
|
|
|
|
# setting the value |
601
|
1535
|
|
|
|
|
2395
|
$save_setting->($self, $name, @_); |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
} else { |
604
|
|
|
|
|
|
|
# getting the value |
605
|
4509
|
|
|
|
|
4961
|
my $val = $get_setting->($self, $name); |
606
|
4509
|
100
|
|
|
|
6588
|
if (defined $val) { |
|
|
100
|
|
|
|
|
|
607
|
1038
|
|
|
|
|
2098
|
return $val; |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
} elsif (ref $self) { |
610
|
|
|
|
|
|
|
# called on an object and no value set, try the class |
611
|
271
|
|
|
|
|
516
|
return $self->class->$name(); |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
} else { |
614
|
|
|
|
|
|
|
# called on a class name |
615
|
3200
|
|
|
|
|
37279
|
my @super = $self->inheritance(); |
616
|
3200
|
|
|
|
|
3369
|
foreach my $super ( @super ) { |
617
|
2581
|
50
|
|
|
|
5509
|
if (my $super_sub = $super->can($name)) { |
618
|
2581
|
|
|
|
|
14890
|
return $super_sub->($super); |
619
|
|
|
|
|
|
|
} |
620
|
|
|
|
|
|
|
} |
621
|
|
|
|
|
|
|
# None of the parent classes implement it, or there aren't |
622
|
|
|
|
|
|
|
# any parent classes |
623
|
619
|
|
|
|
|
3209
|
return $default_messaging_settings{$name}; |
624
|
|
|
|
|
|
|
} |
625
|
|
|
|
|
|
|
} |
626
|
|
|
|
|
|
|
}; |
627
|
|
|
|
|
|
|
}; |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
foreach my $base ( qw( %s_messages_callback queue_%s_messages %s_package |
630
|
|
|
|
|
|
|
%s_file %s_line %s_subroutine ) |
631
|
|
|
|
|
|
|
) { |
632
|
|
|
|
|
|
|
my $method = sprintf($base, $type); |
633
|
|
|
|
|
|
|
my $full_name = $class . '::' . $method; |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
my $method_subref = Sub::Name::subname $full_name => $make_mutator->($method); |
636
|
|
|
|
|
|
|
Sub::Install::install_sub({ |
637
|
|
|
|
|
|
|
code => $method_subref, |
638
|
|
|
|
|
|
|
into => $class, |
639
|
|
|
|
|
|
|
as => $method, |
640
|
|
|
|
|
|
|
}); |
641
|
|
|
|
|
|
|
} |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
my $should_dump_messages = "dump_${type}_messages"; |
644
|
|
|
|
|
|
|
my $dump_mutator = $make_mutator->($should_dump_messages); |
645
|
|
|
|
|
|
|
my @dump_env_vars = map { $_ . uc($should_dump_messages) } ('UR_', 'UR_COMMAND_'); |
646
|
|
|
|
|
|
|
my $should_dump_messages_subref = Sub::Name::subname $class . '::' . $should_dump_messages => sub { |
647
|
1007
|
|
|
1007
|
|
61450
|
my $self = shift; |
|
|
|
|
1007
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
|
1007
|
|
|
|
648
|
1007
|
100
|
|
|
|
1673
|
if (@_) { |
649
|
131
|
|
|
|
|
318
|
return $dump_mutator->($self, @_); |
650
|
|
|
|
|
|
|
} |
651
|
876
|
|
|
|
|
900
|
foreach my $varname ( @dump_env_vars ) { |
652
|
1752
|
50
|
|
|
|
3051
|
return $ENV{$varname} if (defined $ENV{$varname}); |
653
|
|
|
|
|
|
|
} |
654
|
876
|
|
|
|
|
1177
|
return $dump_mutator->($self); |
655
|
|
|
|
|
|
|
}; |
656
|
|
|
|
|
|
|
Sub::Install::install_sub({ |
657
|
|
|
|
|
|
|
code => $should_dump_messages_subref, |
658
|
|
|
|
|
|
|
into => $class, |
659
|
|
|
|
|
|
|
as => $should_dump_messages, |
660
|
|
|
|
|
|
|
}); |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
my $messages_arrayref = "${type}_messages_arrayref"; |
664
|
|
|
|
|
|
|
my $message_arrayref_sub = Sub::Name::subname "${class}::${messages_arrayref}" => sub { |
665
|
104
|
|
|
104
|
|
110
|
my $self = shift; |
|
|
|
|
104
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
|
104
|
|
|
|
666
|
104
|
|
|
|
|
150
|
my $a = $get_setting->($self, $messages_arrayref); |
667
|
104
|
100
|
|
|
|
218
|
if (! defined $a) { |
668
|
20
|
|
|
|
|
57
|
$save_setting->($self, $messages_arrayref, $a = []); |
669
|
|
|
|
|
|
|
} |
670
|
104
|
|
|
|
|
149
|
return $a; |
671
|
|
|
|
|
|
|
}; |
672
|
|
|
|
|
|
|
Sub::Install::install_sub({ |
673
|
|
|
|
|
|
|
code => $message_arrayref_sub, |
674
|
|
|
|
|
|
|
into => $class, |
675
|
|
|
|
|
|
|
as => $messages_arrayref, |
676
|
|
|
|
|
|
|
}); |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
my $array_subname = "${type}_messages"; |
679
|
|
|
|
|
|
|
my $array_subref = Sub::Name::subname "${class}::${array_subname}" => sub { |
680
|
177
|
|
|
177
|
|
23060
|
my $self = shift; |
|
|
|
|
177
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
|
177
|
|
|
|
681
|
177
|
100
|
|
|
|
701
|
my @search = ref($self) |
682
|
|
|
|
|
|
|
? $self |
683
|
|
|
|
|
|
|
: ( $self, $self->__meta__->subclasses_loaded, $self->is_loaded() ); |
684
|
177
|
|
|
|
|
218
|
my %seen; |
685
|
|
|
|
|
|
|
my @all_messages; |
686
|
177
|
|
|
|
|
204
|
foreach my $thing ( @search ) { |
687
|
182
|
50
|
|
|
|
517
|
next if $seen{$thing}++; |
688
|
182
|
|
|
|
|
282
|
my $a = $get_setting->($thing, $messages_arrayref); |
689
|
182
|
100
|
|
|
|
426
|
push @all_messages, $a ? @$a : (); |
690
|
|
|
|
|
|
|
} |
691
|
177
|
|
|
|
|
700
|
return @all_messages; |
692
|
|
|
|
|
|
|
}; |
693
|
|
|
|
|
|
|
Sub::Install::install_sub({ |
694
|
|
|
|
|
|
|
code => $array_subref, |
695
|
|
|
|
|
|
|
into => $class, |
696
|
|
|
|
|
|
|
as => $array_subname, |
697
|
|
|
|
|
|
|
}); |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
my $messageinfo_subname = "${type}_message_source"; |
701
|
|
|
|
|
|
|
my @messageinfo_keys = map { $type . $_ } qw( _message _package _file _line _subroutine ); |
702
|
|
|
|
|
|
|
my $messageinfo_subref = Sub::Name::subname "${class}::${messageinfo_subname}" => sub { |
703
|
36
|
|
|
36
|
|
12322
|
my $self = shift; |
|
|
|
|
36
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
|
36
|
|
|
|
704
|
36
|
|
|
|
|
60
|
return map { $_ => $self->$_ } @messageinfo_keys; |
|
180
|
|
|
|
|
300
|
|
705
|
|
|
|
|
|
|
}; |
706
|
|
|
|
|
|
|
Sub::Install::install_sub({ |
707
|
|
|
|
|
|
|
code => $messageinfo_subref, |
708
|
|
|
|
|
|
|
into => $class, |
709
|
|
|
|
|
|
|
as => $messageinfo_subname, |
710
|
|
|
|
|
|
|
}); |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
# usage messages go to STDOUT, others to STDERR |
713
|
|
|
|
|
|
|
my $default_fh = $type eq 'usage' ? \$stdout : \$stderr; |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
my $should_queue_messages = "queue_${type}_messages"; |
716
|
|
|
|
|
|
|
my $check_callback = "${type}_messages_callback"; |
717
|
|
|
|
|
|
|
my $message_text_prefix = ($type eq 'status' or $type eq 'usage') ? '' : uc($type) . ': '; |
718
|
|
|
|
|
|
|
my $message_package = "${type}_package"; |
719
|
|
|
|
|
|
|
my $message_file = "${type}_file"; |
720
|
|
|
|
|
|
|
my $message_line = "${type}_line"; |
721
|
|
|
|
|
|
|
my $message_subroutine = "${type}_subroutine"; |
722
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
my $messaging_action = $type eq 'fatal' |
724
|
|
|
|
|
|
|
? sub { Carp::croak($message_text_prefix . $_[1]) } |
725
|
|
|
|
|
|
|
: sub { |
726
|
|
|
|
|
|
|
my($self, $msg) = @_; |
727
|
|
|
|
|
|
|
if (my $fh = $self->$should_dump_messages()) { |
728
|
|
|
|
|
|
|
$fh = $$default_fh unless (ref $fh); |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
$fh->print($message_text_prefix . $msg . "\n"); |
731
|
|
|
|
|
|
|
} |
732
|
|
|
|
|
|
|
}; |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
my $logger_subname = "${type}_message"; |
735
|
|
|
|
|
|
|
my $logger_subref = Sub::Name::subname "${class}::${logger_subname}" => sub { |
736
|
571
|
|
|
571
|
|
83754
|
my $self = shift; |
|
|
|
|
571
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
|
571
|
|
|
|
737
|
|
|
|
|
|
|
|
738
|
571
|
100
|
|
|
|
1265
|
if (@_) { |
739
|
383
|
|
|
|
|
457
|
my $msg = shift; |
740
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
# if given multiple arguments, assume it's a format string |
742
|
383
|
100
|
|
|
|
803
|
if(@_) { |
743
|
42
|
|
|
|
|
94
|
$msg = _carp_sprintf($msg, @_); |
744
|
|
|
|
|
|
|
} |
745
|
|
|
|
|
|
|
|
746
|
383
|
100
|
|
|
|
1007
|
defined($msg) && chomp($msg); |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
# old-style callback registered with error_messages_callback |
749
|
383
|
100
|
|
|
|
1205
|
if (my $code = $self->$check_callback()) { |
750
|
188
|
50
|
|
|
|
374
|
if (ref $code) { |
751
|
188
|
|
|
|
|
419
|
$code->($self, $msg); |
752
|
|
|
|
|
|
|
} else { |
753
|
0
|
|
|
|
|
0
|
$self->$code($msg); |
754
|
|
|
|
|
|
|
} |
755
|
|
|
|
|
|
|
} |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
# New-style callback registered as an observer |
758
|
|
|
|
|
|
|
# Some non-UR classes inherit from UR::ModuleBase, and can't __signal |
759
|
383
|
50
|
33
|
|
|
2564
|
if ($UR::initialized && $self->can('__signal_observers__')) { |
760
|
383
|
|
|
|
|
3293
|
$self->__signal_observers__($logger_subname, $msg); |
761
|
|
|
|
|
|
|
} |
762
|
|
|
|
|
|
|
|
763
|
383
|
|
|
|
|
804
|
$save_setting->($self, $logger_subname, $msg); |
764
|
|
|
|
|
|
|
# If the callback set $msg to undef with "$_[1] = undef", then they didn't want the message |
765
|
|
|
|
|
|
|
# processed further |
766
|
383
|
100
|
|
|
|
883
|
if (defined $msg) { |
767
|
272
|
100
|
|
|
|
818
|
if ($self->$should_queue_messages()) { |
768
|
66
|
|
|
|
|
195
|
my $a = $self->$messages_arrayref(); |
769
|
66
|
|
|
|
|
104
|
push @$a, $msg; |
770
|
|
|
|
|
|
|
} |
771
|
|
|
|
|
|
|
|
772
|
272
|
|
|
|
|
801
|
my ($package, $file, $line, $subroutine) = caller; |
773
|
272
|
|
|
|
|
1015
|
$self->$message_package($package); |
774
|
272
|
|
|
|
|
766
|
$self->$message_file($file); |
775
|
272
|
|
|
|
|
751
|
$self->$message_line($line); |
776
|
272
|
|
|
|
|
739
|
$self->$message_subroutine($subroutine); |
777
|
|
|
|
|
|
|
|
778
|
272
|
|
|
|
|
532
|
$self->$messaging_action($msg); |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
} |
781
|
|
|
|
|
|
|
} |
782
|
|
|
|
|
|
|
|
783
|
544
|
|
|
|
|
3596
|
return $get_setting->($self, $logger_subname); |
784
|
|
|
|
|
|
|
}; |
785
|
|
|
|
|
|
|
Sub::Install::install_sub({ |
786
|
|
|
|
|
|
|
code => $logger_subref, |
787
|
|
|
|
|
|
|
into => $class, |
788
|
|
|
|
|
|
|
as => $logger_subname, |
789
|
|
|
|
|
|
|
}); |
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
# "Register" the message type as a valid signal. |
792
|
|
|
|
|
|
|
$UR::Object::Type::STANDARD_VALID_SIGNALS{$logger_subname} = 1; |
793
|
|
|
|
|
|
|
}; |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
sub _carp_sprintf { |
796
|
42
|
|
|
42
|
|
43
|
my $format = shift; |
797
|
42
|
|
|
|
|
69
|
my @list = @_; |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
# warnings weren't very helpful because they wouldn't tell you who passed |
800
|
|
|
|
|
|
|
# in the "bad" format string |
801
|
42
|
|
|
|
|
44
|
my $formatted_string; |
802
|
|
|
|
|
|
|
my $warn_msg; |
803
|
|
|
|
|
|
|
{ |
804
|
42
|
|
|
|
|
42
|
local $SIG{__WARN__} = sub { |
805
|
6
|
|
|
6
|
|
6
|
my $msg = $_[0]; |
806
|
6
|
|
|
|
|
11
|
my ($filename, $line) = (caller)[1, 2]; |
807
|
6
|
|
|
|
|
57
|
my $short_msg = ($msg =~ /(.*) at $filename line $line./)[0]; |
808
|
6
|
|
33
|
|
|
45
|
$warn_msg = ($short_msg || $msg); |
809
|
42
|
|
|
|
|
242
|
}; |
810
|
42
|
|
|
|
|
312
|
$formatted_string = sprintf($format, @list); |
811
|
|
|
|
|
|
|
} |
812
|
42
|
100
|
|
|
|
82
|
if ($warn_msg) { |
813
|
3
|
|
|
|
|
528
|
Carp::carp($warn_msg); |
814
|
|
|
|
|
|
|
} |
815
|
|
|
|
|
|
|
|
816
|
42
|
|
|
|
|
369
|
return $formatted_string; |
817
|
|
|
|
|
|
|
} |
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
# at init time, make messaging subs for the initial message types |
821
|
|
|
|
|
|
|
$create_subs_for_message_type->(__PACKAGE__, $_) foreach @message_types; |
822
|
|
|
|
|
|
|
|
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
sub _current_call_stack |
825
|
|
|
|
|
|
|
{ |
826
|
0
|
|
|
0
|
|
|
my @stack = reverse split /\n/, Carp::longmess("\t"); |
827
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
# Get rid of the final line from carp, showing the line number |
829
|
|
|
|
|
|
|
# above from which we called it. |
830
|
0
|
|
|
|
|
|
pop @stack; |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
# Get rid any other function calls which are inside of this |
833
|
|
|
|
|
|
|
# package besides the first one. This allows wrappers to |
834
|
|
|
|
|
|
|
# get_message to look at just the external call stack. |
835
|
|
|
|
|
|
|
# (i.e. AUTOSUB above, set_message/get_message which called this, |
836
|
|
|
|
|
|
|
# and AUTOLOAD in UniversalParent) |
837
|
0
|
|
0
|
|
|
|
pop(@stack) while ($stack[-1] =~ /^\s*(UR::ModuleBase|UR)::/ && $stack[-2] && $stack[-2] =~ /^\s*(UR::ModuleBase|UR)::/); |
|
|
|
0
|
|
|
|
|
838
|
|
|
|
|
|
|
|
839
|
0
|
|
|
|
|
|
return \@stack; |
840
|
|
|
|
|
|
|
} |
841
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
1; |
844
|
|
|
|
|
|
|
__END__ |