File Coverage

blib/lib/Perl/RunEND.pm
Criterion Covered Total %
statement 27 58 46.5
branch 0 12 0.0
condition 0 3 0.0
subroutine 9 11 81.8
pod 0 1 0.0
total 36 85 42.3


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