line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# /* vim:et: set ts=4 sw=4 sts=4 tw=78: */ |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package Perl::RunEND; |
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
1361
|
use 5.006; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
42
|
|
6
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
43
|
|
7
|
1
|
|
|
1
|
|
21
|
use warnings FATAL => 'all'; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
48
|
|
8
|
|
|
|
|
|
|
#use criticism 'brutal'; # use critic with a ~/.perlcriticrc |
9
|
1
|
|
|
1
|
|
6
|
use Carp qw/croak/; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
68
|
|
10
|
1
|
|
|
1
|
|
1270
|
use File::Temp qw/ tempfile tempdir tmpnam /; |
|
1
|
|
|
|
|
22747
|
|
|
1
|
|
|
|
|
84
|
|
11
|
1
|
|
|
1
|
|
8
|
use File::Basename; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
67
|
|
12
|
1
|
|
|
1
|
|
1209
|
use Getopt::Long; |
|
1
|
|
|
|
|
12337
|
|
|
1
|
|
|
|
|
8
|
|
13
|
1
|
|
|
1
|
|
197
|
use Config; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
46
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 NAME |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
Perl::RunEND - Use __END__ for working code examples, self testing, executing |
18
|
|
|
|
|
|
|
code, etc. |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
A common best-practice under Python is to include a self-test at the end every |
21
|
|
|
|
|
|
|
module - especially if the module is largely standalone. In Python this is |
22
|
|
|
|
|
|
|
done via: if __name__ == '__main__': |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
In Perl, we have an __END__ available where we often put test code or notes |
25
|
|
|
|
|
|
|
or comments, etc. Currently there is no way to actually execute this code, |
26
|
|
|
|
|
|
|
execpt by using the DATA filehandle. It would be handy if we could put |
27
|
|
|
|
|
|
|
actual test examples in the __END__ block which would would be executed |
28
|
|
|
|
|
|
|
if the module is run as 'self'. Or to just test a script or code snippets, |
29
|
|
|
|
|
|
|
by running the same file you are editing. |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
=head1 VERSION |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
Version 0.01 |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=cut |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
#our $VERSION = '0.01'; |
39
|
|
|
|
|
|
|
#major-version.minor-revision.bugfix |
40
|
1
|
|
|
1
|
|
904
|
use version; our $VERSION = qv('0.1.0'); |
|
1
|
|
|
|
|
2255
|
|
|
1
|
|
|
|
|
6
|
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=head1 SYNOPSIS |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
If module is called as 'self' run the code beneath __END__. |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
perl-run-end /opt/Module/Whatever/YourModule.pm |
49
|
|
|
|
|
|
|
# displays |
50
|
|
|
|
|
|
|
FOOfunction1 called |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
Where the contents of ModuleWhatever/YourModule.pm |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
package YourModule; |
55
|
|
|
|
|
|
|
use strict; |
56
|
|
|
|
|
|
|
sub new { |
57
|
|
|
|
|
|
|
my $class = shift; |
58
|
|
|
|
|
|
|
my $self = bless {}, $class; |
59
|
|
|
|
|
|
|
$self->{foo} = 'FOO'; |
60
|
|
|
|
|
|
|
return $self; |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
sub function1 { |
63
|
|
|
|
|
|
|
return 'function1 called'; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
1; # End of Perl::RunEND |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
__END__ |
68
|
|
|
|
|
|
|
use strict; |
69
|
|
|
|
|
|
|
use warnings; |
70
|
|
|
|
|
|
|
use YourModule; |
71
|
|
|
|
|
|
|
my $ym = YourModule->new(); |
72
|
|
|
|
|
|
|
warn $ym->{foo}; |
73
|
|
|
|
|
|
|
warn $ym->function1; |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# you may have to add the module path to your @INC |
76
|
|
|
|
|
|
|
perl-run-end -i /opt/Module/Whatever/Mod /opt/Module/Whatever/Mod/YourModule.pm |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head1 DESCRIPTION |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
Some people like to create their POD below the __END__ literal in the modules |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
This module could be useful for proving your synopsis and POD examples are working code. |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
Consider the following POD: |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=head1 SYNOPSIS |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
use My::MyModulePod; |
89
|
|
|
|
|
|
|
my $mm = My::MyModulePod->new(); |
90
|
|
|
|
|
|
|
print $mm->function1,"\n"; |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=cut |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
# perdoc does not parse this code but perl-run-end does execute it |
95
|
|
|
|
|
|
|
use My::MyModulePod; |
96
|
|
|
|
|
|
|
my $mm = My::MyModulePod->new(); |
97
|
|
|
|
|
|
|
print "test synopsis\n"; |
98
|
|
|
|
|
|
|
print $mm->function1,"\n"; |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=head2 function1 |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
provides useful funtion type access |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
$mm->function1; |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=cut |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
print "test method definition\n"; |
109
|
|
|
|
|
|
|
print $mm->function1,"\n"; |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=head1 SUBROUTINES/METHODS |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
This module is not meant to be called directly, it does the work for the |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
command line tool: perl-run-end |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=cut |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub _get_inc_if_set { |
121
|
0
|
|
|
0
|
|
|
my $inc = q{}; |
122
|
0
|
|
|
|
|
|
GetOptions('i=s' => \$inc); |
123
|
0
|
0
|
|
|
|
|
return $inc if $inc; |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub run { |
127
|
0
|
|
|
0
|
0
|
|
my $inc = _get_inc_if_set(); |
128
|
|
|
|
|
|
|
|
129
|
0
|
0
|
|
|
|
|
open my $opm, '<', $ARGV[0] or croak "cant open Script/Module $!"; |
130
|
0
|
|
|
|
|
|
my ($pm, $lines, $flines); |
131
|
0
|
|
|
|
|
|
while (my $line = <$opm>) { |
132
|
0
|
|
|
|
|
|
$lines++; |
133
|
0
|
|
|
|
|
|
$pm .= $line; |
134
|
0
|
0
|
|
|
|
|
$flines = $lines if $line =~ m/^__END__$/; |
135
|
|
|
|
|
|
|
} |
136
|
0
|
|
|
|
|
|
close $opm; |
137
|
|
|
|
|
|
|
# XXX do we want to support ^D - perldata.html#Special-Literals |
138
|
0
|
|
|
|
|
|
$pm =~ s/.*__END__//sxg; |
139
|
0
|
|
|
|
|
|
$lines = $flines; |
140
|
|
|
|
|
|
|
|
141
|
0
|
|
|
|
|
|
my ($fh, $filename) = tempfile(); |
142
|
0
|
|
|
|
|
|
my $cmd_out = tmpnam(); |
143
|
0
|
|
|
|
|
|
print $fh $pm; |
144
|
0
|
|
|
|
|
|
close $fh; |
145
|
|
|
|
|
|
|
#print qx/cat $filename/; |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
# get path to systems perl |
148
|
0
|
|
|
|
|
|
my $perl = $Config{perlpath}; |
149
|
0
|
0
|
0
|
|
|
|
$perl .= $Config{_exe} if $^O ne 'VMS' and $perl !~ /$Config{_exe}$/i; |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
# if self testing module, include in path |
152
|
0
|
|
|
|
|
|
my $use_lib = dirname($ARGV[0]); |
153
|
|
|
|
|
|
|
#warn qq{$perl -I $use_lib $filename 2>&1 > $cmd_out}; |
154
|
0
|
|
|
|
|
|
my $add_inc = q{}; |
155
|
0
|
0
|
|
|
|
|
$add_inc = " -I $inc " if $inc; |
156
|
|
|
|
|
|
|
#warn qq{$perl -I $use_lib $add_inc $filename 2>&1 > $cmd_out}; |
157
|
0
|
|
|
|
|
|
my $excd = qx{$perl -I $use_lib $add_inc $filename 2>&1 > $cmd_out}; |
158
|
|
|
|
|
|
|
#warn $excd; |
159
|
0
|
|
|
|
|
|
$excd =~ s/line\s(\d+)/line @{[$1+$lines]}/g; |
|
0
|
|
|
|
|
|
|
160
|
0
|
|
|
|
|
|
print $excd; |
161
|
0
|
0
|
|
|
|
|
open my $co, '<', $cmd_out or croak "cant open outfile $!"; |
162
|
0
|
|
|
|
|
|
{ local $/; print <$co>; } |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
163
|
0
|
|
|
|
|
|
close $co; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=head1 AUTHOR |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
David Wright, C<< >> |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=head1 BUGS |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, or through |
173
|
|
|
|
|
|
|
the web interface at L. I will be notified, and then you'll |
174
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes. |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=head1 DIAGNOSTICS |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
If you run a module: |
179
|
|
|
|
|
|
|
perl-run-end /Users/dwright/perl/Perl-RunEND/t/data/My/MyModulePod.pm |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
and recieve an error such as: Can't locate My/MyModulePod.pm in @INC (@INC contains: |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
You need to include the needed module in the @INC path, for instance: |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
perl-run-end -i /Users/dwright/perl/Perl-RunEND/t/data /Users/dwright/perl/Perl-RunEND/t/data/My/MyModulePod.pm |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
Additionally, (depending on your platform?) adjusting the PERL5LIB path, like this should work: |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
PERL5LIB=$PERL5LIB:/Users/dwright/perl/Perl-RunEND/t/data perl-run-end /Users/dwright/perl/Perl-RunEND/t/data/My/MyModulePod.pm |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=head1 SUPPORT |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
perldoc Perl::RunEND |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
You can also look for information at: |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=over 4 |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker (report bugs here) |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
L |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
L |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
=item * CPAN Ratings |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
L |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=item * Search CPAN |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
L |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
=back |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
this module was created with module-starter |
224
|
|
|
|
|
|
|
module-starter --module=Perl::RunEND --author="David Wright" --mb --email=dvwright@cpan.org |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
Copyright 2012 David Wright. |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
232
|
|
|
|
|
|
|
under the terms of the the Artistic License (2.0). You may obtain a |
233
|
|
|
|
|
|
|
copy of the full license at: |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
L |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
Any use, modification, and distribution of the Standard or Modified |
238
|
|
|
|
|
|
|
Versions is governed by this Artistic License. By using, modifying or |
239
|
|
|
|
|
|
|
distributing the Package, you accept this license. Do not use, modify, |
240
|
|
|
|
|
|
|
or distribute the Package, if you do not accept this license. |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
If your Modified Version has been derived from a Modified Version made |
243
|
|
|
|
|
|
|
by someone other than you, you are nevertheless required to ensure that |
244
|
|
|
|
|
|
|
your Modified Version complies with the requirements of this license. |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
This license does not grant you the right to use any trademark, service |
247
|
|
|
|
|
|
|
mark, tradename, or logo of the Copyright Holder. |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
This license includes the non-exclusive, worldwide, free-of-charge |
250
|
|
|
|
|
|
|
patent license to make, have made, use, offer to sell, sell, import and |
251
|
|
|
|
|
|
|
otherwise transfer the Package with respect to any patent claims |
252
|
|
|
|
|
|
|
licensable by the Copyright Holder that are necessarily infringed by the |
253
|
|
|
|
|
|
|
Package. If you institute patent litigation (including a cross-claim or |
254
|
|
|
|
|
|
|
counterclaim) against any party alleging that the Package constitutes |
255
|
|
|
|
|
|
|
direct or contributory patent infringement, then this Artistic License |
256
|
|
|
|
|
|
|
to you shall terminate on the date that such litigation is filed. |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER |
259
|
|
|
|
|
|
|
AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. |
260
|
|
|
|
|
|
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
261
|
|
|
|
|
|
|
PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY |
262
|
|
|
|
|
|
|
YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR |
263
|
|
|
|
|
|
|
CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR |
264
|
|
|
|
|
|
|
CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, |
265
|
|
|
|
|
|
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
=cut |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
1; # End of Perl::RunEND |