line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package App::Fetchware::CreateConfigOptions; |
2
|
|
|
|
|
|
|
our $VERSION = '1.016'; # VERSION: generated by DZP::OurPkgVersion |
3
|
|
|
|
|
|
|
# ABSTRACT: Used by fetchware extensions to create their configuration options. |
4
|
3
|
|
|
3
|
|
708
|
use strict; |
|
3
|
|
|
|
|
3
|
|
|
3
|
|
|
|
|
65
|
|
5
|
3
|
|
|
3
|
|
9
|
use warnings; |
|
3
|
|
|
|
|
3
|
|
|
3
|
|
|
|
|
60
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
# CPAN modules making Fetchwarefile better. |
8
|
3
|
|
|
3
|
|
8
|
use Sub::Mage; |
|
3
|
|
|
|
|
3
|
|
|
3
|
|
|
|
|
13
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# App::Fetchware::CreateConfigOptions uses _make_config_sub() from |
11
|
|
|
|
|
|
|
# App::Fetchware, so I must use() it, so I can use it. |
12
|
3
|
|
|
3
|
|
2771
|
use App::Fetchware; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
426
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
# Enable Perl 6 knockoffs, and use 5.10.1, because smartmatching and other |
15
|
|
|
|
|
|
|
# things in 5.10 were changed in 5.10.1+. |
16
|
3
|
|
|
3
|
|
51
|
use 5.010001; |
|
3
|
|
|
|
|
6
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# Don't use Exporter's import; instead, provide your own. This is all ExportAPI |
19
|
|
|
|
|
|
|
# does. Provide an import() method, so that it can set up correct exports, and |
20
|
|
|
|
|
|
|
# ensure that your fetchware extension implementes all of fetchware's API |
21
|
|
|
|
|
|
|
# subroutines at compile time. |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
sub import { |
26
|
14
|
|
|
14
|
|
2462
|
my ($class, @opts) = @_; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# Just return success if user specified no options, because that just means |
29
|
|
|
|
|
|
|
# the user wanted to load the module, but not actually import() anything. |
30
|
14
|
100
|
|
|
|
40
|
return 'Success' if @opts == 0; |
31
|
|
|
|
|
|
|
|
32
|
13
|
|
|
|
|
18
|
my $caller = caller; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# Forward call to _create_config_options(), which does all the work. |
35
|
|
|
|
|
|
|
# Note how the caller of import() is forwarded on to |
36
|
|
|
|
|
|
|
# _create_config_options(). |
37
|
13
|
|
|
|
|
19
|
_create_config_options($caller, @opts); |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
# Make _export_api() "invisible." users should only ever actually use import(), |
43
|
|
|
|
|
|
|
# and technically they should never even use import; instead, they should just |
44
|
|
|
|
|
|
|
# use ExportAPI, and Perl will call import() for them. |
45
|
|
|
|
|
|
|
#=head2 _create_config_options() |
46
|
|
|
|
|
|
|
# |
47
|
|
|
|
|
|
|
# # _create_config_options() *must* be called in a BEGIN block, because it |
48
|
|
|
|
|
|
|
# # creates subroutines that have prototypes, and prototypes *must* be known |
49
|
|
|
|
|
|
|
# # about at compile time not run time! |
50
|
|
|
|
|
|
|
# BEGIN { |
51
|
|
|
|
|
|
|
# _create_config_options( |
52
|
|
|
|
|
|
|
# $callers_package, |
53
|
|
|
|
|
|
|
# ONE => [qw( |
54
|
|
|
|
|
|
|
# page_name |
55
|
|
|
|
|
|
|
# html_page_url |
56
|
|
|
|
|
|
|
# user_agent |
57
|
|
|
|
|
|
|
# html_treebuilder_callback |
58
|
|
|
|
|
|
|
# download_links_callback |
59
|
|
|
|
|
|
|
# )], |
60
|
|
|
|
|
|
|
# BOOLEAN => [qw( |
61
|
|
|
|
|
|
|
# keep_destination_directory |
62
|
|
|
|
|
|
|
# )], |
63
|
|
|
|
|
|
|
# IMPORT => [qw( |
64
|
|
|
|
|
|
|
# temp_dir |
65
|
|
|
|
|
|
|
# )], |
66
|
|
|
|
|
|
|
# ); |
67
|
|
|
|
|
|
|
# } |
68
|
|
|
|
|
|
|
# |
69
|
|
|
|
|
|
|
#Creates configuration options of the same types App::Fetchware uses. These |
70
|
|
|
|
|
|
|
#are: |
71
|
|
|
|
|
|
|
# |
72
|
|
|
|
|
|
|
#=over |
73
|
|
|
|
|
|
|
# |
74
|
|
|
|
|
|
|
#=item 1. ONE - Stores one and only ever one value. If the configuration option |
75
|
|
|
|
|
|
|
#is used more than once, an exception is thrown. |
76
|
|
|
|
|
|
|
# |
77
|
|
|
|
|
|
|
#=item 2. ONEARRREF - Stores one or more values. But only stores a list when |
78
|
|
|
|
|
|
|
#provided a list when you call it such as |
79
|
|
|
|
|
|
|
#C would create a |
80
|
|
|
|
|
|
|
#configuration option with three values. However, if a ONEARRREF is called more |
81
|
|
|
|
|
|
|
#than once, and exception is also thrown. |
82
|
|
|
|
|
|
|
# |
83
|
|
|
|
|
|
|
#=item 3. MANY - Stores many values one at a time just like ONEARRREF, but can |
84
|
|
|
|
|
|
|
#also be called any number of times, and values are appended to any already |
85
|
|
|
|
|
|
|
#existing ones. |
86
|
|
|
|
|
|
|
# |
87
|
|
|
|
|
|
|
#=item 4. BOOLEAN - Stores true or false values such as C or |
88
|
|
|
|
|
|
|
#C or C |
89
|
|
|
|
|
|
|
# |
90
|
|
|
|
|
|
|
#=back |
91
|
|
|
|
|
|
|
# |
92
|
|
|
|
|
|
|
#In addition to App::Fetchware's types, _create_config_options() features an |
93
|
|
|
|
|
|
|
#additional type: |
94
|
|
|
|
|
|
|
# |
95
|
|
|
|
|
|
|
#=over |
96
|
|
|
|
|
|
|
# |
97
|
|
|
|
|
|
|
#=item 5. IMPORT - This option is documented only for completness, because it is |
98
|
|
|
|
|
|
|
#recommended that you use L, and any |
99
|
|
|
|
|
|
|
#App::Fetchware API subroutines that you C<'KEEP'> |
100
|
|
|
|
|
|
|
#L will automatically call |
101
|
|
|
|
|
|
|
#_create_config_options() for you to import any fetchware API subroutines that |
102
|
|
|
|
|
|
|
#you want your fetchware extension to reuse. See L for |
103
|
|
|
|
|
|
|
#details. You can specify the C option, |
104
|
|
|
|
|
|
|
#C<_create_config_options(..., NOIMPORT =E 1);>, to avoid the automatic |
105
|
|
|
|
|
|
|
#importing of App::Fetchware configuration options. |
106
|
|
|
|
|
|
|
# |
107
|
|
|
|
|
|
|
#=back |
108
|
|
|
|
|
|
|
# |
109
|
|
|
|
|
|
|
#Note: you must prepend your options with the $callers_package, which is the |
110
|
|
|
|
|
|
|
#package that you want the specified subroutines to be created in. |
111
|
|
|
|
|
|
|
# |
112
|
|
|
|
|
|
|
#Just use any of C, C, C, or C as faux hash keys |
113
|
|
|
|
|
|
|
#being sure to wrap their arguments in a array reference brackets C<[]> |
114
|
|
|
|
|
|
|
# |
115
|
|
|
|
|
|
|
#_create_config_options() also takes the faux hash key C this hash key |
116
|
|
|
|
|
|
|
#does not create new configuration options, but instead imports already defined |
117
|
|
|
|
|
|
|
#ones from App::Fetchware allowing you to reuse popular configuration options |
118
|
|
|
|
|
|
|
#like C or C in your fetchware extension. |
119
|
|
|
|
|
|
|
# |
120
|
|
|
|
|
|
|
#=over |
121
|
|
|
|
|
|
|
# |
122
|
|
|
|
|
|
|
#=item LIMITATION |
123
|
|
|
|
|
|
|
# |
124
|
|
|
|
|
|
|
#_create_config_options() creates subroutines that have prototypes, but in order |
125
|
|
|
|
|
|
|
#for perl to honor those prototypes perl B know about them at compile-time; |
126
|
|
|
|
|
|
|
#therefore, that is why _create_config_options() must be called inside a C |
127
|
|
|
|
|
|
|
#block. |
128
|
|
|
|
|
|
|
# |
129
|
|
|
|
|
|
|
#=back |
130
|
|
|
|
|
|
|
# |
131
|
|
|
|
|
|
|
#=cut |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub _create_config_options { |
134
|
26
|
|
|
26
|
|
982
|
my ($callers_package, %opts) = @_; |
135
|
|
|
|
|
|
|
|
136
|
26
|
|
|
|
|
50
|
for my $value_key (keys %opts) { |
137
|
39
|
|
|
|
|
26
|
for my $sub_name (@{$opts{$value_key}}) { |
|
39
|
|
|
|
|
65
|
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# IMPORT subroutines are not actually "imported." Instead, they are |
140
|
|
|
|
|
|
|
# "made" in the correct package by App::Fetchware's config subroutine |
141
|
|
|
|
|
|
|
# function factory, _make_config_sub(). |
142
|
130
|
100
|
|
|
|
172
|
if ($value_key ne 'IMPORT') { |
143
|
76
|
|
|
|
|
126
|
App::Fetchware::_make_config_sub($sub_name, $value_key, |
144
|
|
|
|
|
|
|
$callers_package); |
145
|
|
|
|
|
|
|
} else { |
146
|
54
|
50
|
|
|
|
1172
|
die <
|
|
9756
|
|
|
|
|
10151
|
|
147
|
|
|
|
|
|
|
App-Fetchware-Util: App::Fetchware has not been loaded. How can you import a |
148
|
|
|
|
|
|
|
subroutine from App::Fetchware if you have not yet loaded it yet? Please load |
149
|
|
|
|
|
|
|
App::Fetchware [use App::Fetchware;] and try again. |
150
|
|
|
|
|
|
|
EOD |
151
|
54
|
50
|
|
|
|
404
|
clone($sub_name => (from => 'App::Fetchware', to => $callers_package)) |
152
|
|
|
|
|
|
|
or die <
|
153
|
|
|
|
|
|
|
App-Fetchware-Util: Failed to clone the specified subroutine [$sub_name] from |
154
|
|
|
|
|
|
|
App::Fetchware into your namespace [$callers_package]. You probably just need to |
155
|
|
|
|
|
|
|
load fetchware [use App::Fetchware;] inside your fetchware extension. |
156
|
|
|
|
|
|
|
EOD |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
# Be sure to @EXPORT the newly minted subroutine. |
160
|
130
|
|
|
|
|
1769
|
_add_export($sub_name, $callers_package); |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# Hide it's POD since it's an '_' hidden subroutine I don't want fetchware |
170
|
|
|
|
|
|
|
# extensions to use. |
171
|
|
|
|
|
|
|
#=head2 _add_export() |
172
|
|
|
|
|
|
|
# |
173
|
|
|
|
|
|
|
# _add_export(start => caller); |
174
|
|
|
|
|
|
|
# |
175
|
|
|
|
|
|
|
#Adds the specified subroutine to the specified caller's @EXPORT variable, so |
176
|
|
|
|
|
|
|
#that when the specified package is imported the specified subroutine is imported |
177
|
|
|
|
|
|
|
#as well. |
178
|
|
|
|
|
|
|
# |
179
|
|
|
|
|
|
|
#=cut |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
sub _add_export { |
182
|
179
|
|
|
179
|
|
157
|
my ($sub_to_export, $caller) = @_; |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
{ |
185
|
3
|
|
|
3
|
|
16
|
no strict 'refs'; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
373
|
|
|
179
|
|
|
|
|
116
|
|
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
# If the $caller has not declared @EXPORT for us, then we'll do it here |
188
|
|
|
|
|
|
|
# ourselves, so you don't need to declare a variable in your fetchware |
189
|
|
|
|
|
|
|
# extension that you never even use yourself. |
190
|
|
|
|
|
|
|
# |
191
|
|
|
|
|
|
|
#The crazy *{...} contraption looks up @$caller::EXPORT up in the stash, |
192
|
|
|
|
|
|
|
#and checks if it's defined in the stash, and if there's a stash entry, |
193
|
|
|
|
|
|
|
#then it has been defined, and if not, then the variable is undeclared, |
194
|
|
|
|
|
|
|
#so then delare it using the crazy eval. |
195
|
|
|
|
|
|
|
# |
196
|
|
|
|
|
|
|
#Also, note that use vars is used in favor of our, because our variables |
197
|
|
|
|
|
|
|
#are bizarrely lexically scoped, which is insane. Why would a global be |
198
|
|
|
|
|
|
|
#lexically scoped it's a global isn't it. But if you think that's |
199
|
|
|
|
|
|
|
#bizarre, check this out, use vars is file scoped. Again, how is a |
200
|
|
|
|
|
|
|
#global file scoped? Perhaps just the variable you declare with our or |
201
|
|
|
|
|
|
|
#use vars is lexical or file scoped, but the stash entry it creates |
202
|
|
|
|
|
|
|
#actually is global??? |
203
|
179
|
100
|
|
|
|
116
|
unless (defined *{ $caller . '::EXPORT' }{ARRAY}) { |
|
179
|
|
|
|
|
429
|
|
204
|
7
|
|
|
|
|
8
|
my $eval = 'use vars @$caller::EXPORT; 1;'; |
205
|
7
|
|
|
|
|
17
|
$eval =~ s/\$caller/$caller/; |
206
|
3
|
50
|
|
3
|
|
12
|
eval $eval or die <
|
|
3
|
|
|
2
|
|
5
|
|
|
3
|
|
|
1
|
|
41
|
|
|
2
|
|
|
1
|
|
9
|
|
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
23
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
11
|
|
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
11
|
|
|
7
|
|
|
|
|
357
|
|
207
|
|
|
|
|
|
|
App-Fetchware-Util: Huh?!? For some reason fetchware failed to create the |
208
|
|
|
|
|
|
|
necessary \@EXPORT variable in the specified caller's package [$caller]. This |
209
|
|
|
|
|
|
|
just shouldn't happen, and is probably an internal bug in fetchware. Perhaps |
210
|
|
|
|
|
|
|
the package specified in [$caller] has not been defined. Exception: |
211
|
|
|
|
|
|
|
[$@] |
212
|
|
|
|
|
|
|
EOD |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
# export *all* @api_subs. |
216
|
179
|
|
|
|
|
169
|
push @{"${caller}::EXPORT"}, $sub_to_export; |
|
179
|
|
|
|
|
265849
|
|
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
1; |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
=pod |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
=head1 NAME |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
App::Fetchware::CreateConfigOptions - Used by fetchware extensions to create their configuration options. |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
=head1 VERSION |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
version 1.016 |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=head1 SYNOPSIS |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
use App::Fetchware::ExportAPI KEEP => [qw(start end)], |
237
|
|
|
|
|
|
|
OVERRIDE => |
238
|
|
|
|
|
|
|
[qw(lookup download verify unarchive build install uninstall)]; |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
=head1 DESCRIPTION |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
App::Fetchware::ExportAPI is a utility helper class for fetchware extensions. It |
243
|
|
|
|
|
|
|
makes it easy to ensure that your fetchware extension implements or imports all |
244
|
|
|
|
|
|
|
of App::Fetchware's required API subroutines. |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
See section L in App::Fetchware's |
247
|
|
|
|
|
|
|
documentation for more information on how to create your very own fetchware |
248
|
|
|
|
|
|
|
extension. |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=head1 CREATECONFIGOPTIONS'S API METHODS |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
App::Fetchware::CreateConfigOptions (CreateConfigOptions) has only one |
253
|
|
|
|
|
|
|
user-servicable part--it's import() method. It works just like L's |
254
|
|
|
|
|
|
|
import() method except it takes arguments differently, and checks it's arguments |
255
|
|
|
|
|
|
|
more thuroughly. |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
=head2 import() |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
# You don't actually call import() unless you're doing something weird. |
260
|
|
|
|
|
|
|
# Instead, use calls import for you. |
261
|
|
|
|
|
|
|
use App::Fetchware::CreateConfigOptions |
262
|
|
|
|
|
|
|
ONE => [qw( |
263
|
|
|
|
|
|
|
page_name |
264
|
|
|
|
|
|
|
html_page_url |
265
|
|
|
|
|
|
|
user_agent |
266
|
|
|
|
|
|
|
html_treebuilder_callback |
267
|
|
|
|
|
|
|
download_links_callback |
268
|
|
|
|
|
|
|
)], |
269
|
|
|
|
|
|
|
BOOLEAN => [qw( |
270
|
|
|
|
|
|
|
keep_destination_directory |
271
|
|
|
|
|
|
|
)], |
272
|
|
|
|
|
|
|
IMPORT => [qw( |
273
|
|
|
|
|
|
|
temp_dir |
274
|
|
|
|
|
|
|
)], |
275
|
|
|
|
|
|
|
; |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
Creates configuration options of the same types App::Fetchware uses. These |
278
|
|
|
|
|
|
|
are: |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=over |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=item 1. ONE - Stores one and only ever one value. If the configuration option |
283
|
|
|
|
|
|
|
is used more than once, an exception is thrown. |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=item 2. ONEARRREF - Stores one or more values. But only stores a list when |
286
|
|
|
|
|
|
|
provided a list when you call it such as |
287
|
|
|
|
|
|
|
C would create a |
288
|
|
|
|
|
|
|
configuration option with three values. However, if a ONEARRREF is called more |
289
|
|
|
|
|
|
|
than once, and exception is also thrown. |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
=item 3. MANY - Stores many values one at a time just like ONEARRREF, but can |
292
|
|
|
|
|
|
|
also be called any number of times, and values are appended to any already |
293
|
|
|
|
|
|
|
existing ones. |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=item 4. BOOLEAN - Stores true or false values such as C or |
296
|
|
|
|
|
|
|
C or C |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
=back |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
In addition to App::Fetchware's types, import() features an |
301
|
|
|
|
|
|
|
additional type: |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=over |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=item 5. IMPORT - the C this hash key does not create new configuration |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
options, but instead imports already defined ones from App::Fetchware allowing |
308
|
|
|
|
|
|
|
you to reuse popular configuration options like C or C in |
309
|
|
|
|
|
|
|
your fetchware extension. |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
=back |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
Just use any of C, C, C, or C as faux hash keys |
314
|
|
|
|
|
|
|
being sure to wrap their arguments in array reference brackets C<[]> |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
=over |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=item LIMITATION |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
import() creates subroutines that have prototypes, but in order |
321
|
|
|
|
|
|
|
for perl to honor those prototypes perl B know about them at compile-time; |
322
|
|
|
|
|
|
|
therefore, that is why import() must be called inside a C |
323
|
|
|
|
|
|
|
block. The best and most obvious way of doing that is use |
324
|
|
|
|
|
|
|
C |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
=back |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=head1 ERRORS |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
As with the rest of App::Fetchware, App::Fetchware::ExportAPI does not return |
331
|
|
|
|
|
|
|
any error codes; instead, all errors are die()'d if it's Test::Fetchware's error, |
332
|
|
|
|
|
|
|
or croak()'d if its the caller's fault. |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=head1 AUTHOR |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
David Yingling |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
This software is copyright (c) 2016 by David Yingling. |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
343
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=cut |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
__END__ |