In this Meditation I provide an overview of literate programming(LP)
with perl. In the interest of not being too wordy I will omit much discussion
of the theory of literate programming. There is an excellent article
here by Mark-Jason Dominus
which discusses literate programming in some detail. By not belaboring the more theoretical points
what remains here is essentially a quickstart guide in LP using the
perlWEB tool. Hopefully, with a short and practical
introduction to LP the use of the technique may find some more widespread use. My goal with this Meditation is to remove the initial barrier to entry
to using perlWEB. I found getting my first working example off the ground and to understand the main points of the tool
took me longer than I would have liked!
LP is basically a method of writing code in which you write documentation and code in the same
file(s). I became drawn to LP as I realized that it greatly reduced the amount of time I would later spend
either re-educating myself about some old code of my own or explaining my code to later maintainers.
Even with well written comments within the source files I found that LP provided so much more breadth and depth of
information that the greater up front time investment was always well worth it.
Here I will create a file based on the code posted to this
node.
This has the benefit of providing a concise example that displays many features of LP with perlWEB
but has the drawback of not impressing you, the reader, with how much easier your life will be in maintaining and
updating a significant codebase. Also, as with all well intentioned examples it is a little convoluted for the sake of
exposition.
#*A small script to check the sum of a number's digits recursively
(until single digit of length).
#p This unnamed module begins the perl source.
use strict;
use warnings;
#<Main Program#>
#<subroutine to sum the digits recursively#>
# The Main Program.
Here we define the main program.
We declare a variable, |$total1|, to handle
the value returned from the subroutine |sub1|. In this
example version of the program we are only going to
exam the number 1818 to demonstrate
that we get the correct result of 9. If we do get this
result than we |print| a confirmation. Note also the use
of |perlWEB|'s macro ability.
#d TEST_NUMBER=1818
#<Main Program#>=
my $tota11;
for my $num (TEST_NUMBER..TEST_NUMBER){
my $tota11 = &spl($num);
print "$num == 9\n" if ($tota11 == 9);
}
# The subroutine that handles all of the essential computation.
The algorithm is as follows:<br>
• |$total|=the sum of the digits of what is
expected to be the sole(or first) argument to |sp1|<br>
• if |$total| has 1 digit then print it out<br>
otherwise…<br>
• call |sp1| again with |$total| as the argument
#<subroutine to sum the digits recursively#>=
sub spl{
my ($num1) =@_; #we can still have inline comments as well.
my $total = 0;
$total = $total + $_ for (split '', $num1);#here $total is
#the sum of all the digits of $num1
my $len = length ($total);
return $total if ($len == 1);
&spl($total) if ($len != 1);
}
If the above code is in a file called example.w then the command
w2h example.w -o example.html
will create the documentation file that looks like
this. Nice, isn't it! Imagine giving that
to the developer responsible for maintaining your code! This is the sort of document I wish I started each job with!
The process of creating that documentation from the LP source file is called WEAVE-ing.
Now, to create the perl source file(TANGLE-ing) for the interpreter to actually run we need to use the command
w2p example.w -o example.pl
Here is what example.pl will look like:
use strict;
use warnings;
my $tota11;
for my $num (1818..1818){
my $tota11 = &spl($num);
print "$num == 9\n" if ($tota11 == 9);
}
sub spl{
my ($num1) =@_; #we can still have inline comments as well.
my $total = 0;
$total = $total + $_ for (split '', $num1);#here $total is the
#sum of all the digits of $num1
my $len = length ($total);
return $total if ($len == 1);
&spl($total) if ($len != 1);
}
The perlWEB documentation covers the full process of how the source file is assembled. Please do refer to
it when you get a chance but for now we need only concern ourselves with a few key points:
• The perlWEB source file has a number of sections.
• The starred sections are major headings and we only have one.
Most sections have a name but there may be any number of unnamed sections.
• Unnamed sections are the sections that
begin with #p. There must be at least one unnamed section. I find it convenient to put it right in the beginning.
• At several points raw html is added to enhance the readability of the documentation.
Here is what I left out:
• change files
• file includes
• … and a ton of fiddly details. My goal here is to give a quickstart guide for the impatient but yet still diligent perl developer.
I am not trying to re-write he perlWEB manual but simply try and make it more accessible.
Some final notes that I recorded while writing this:
0. I have been informed that he book Elements of Programming with Perl discusses literate
programming with perl in Chapter 9. I do not own this book nor
have I ever read the text itself. I have read excerpts on Amazon.com
and have looked at the freely downloadable source
code.
From the author's file pqtangle.pdf it appears he discusses a system
developed in the text that uses a syntax similar to noweb. noweb
is a language agnostic literate programming tool which has many merits.
However, for the purposes of this article I have focused on perlWEB. The main
reason for this is that unlike noweb and many other literate programming
tools perlWEB's weave output is in html as opposed to TeX or LaTeX and I
believe that html is much more accessible for the majority of working
developers than TeX or LaTeX. When one sees that most literate programming
adherents are Math and Computer Science academics I think it lends credibility to the
argument that the hurdle of learning TeX or LaTeX is sufficient to
discourage more widespread adoption of these techniques.
1. At the first run of w2p I get the following error:
$ ./w2p temp.w
./w2p: line 29: /usr/lib/cpp: No such file or directory
If you have this problem the fix is easy...
This is fixed by usingthe right path. On my machine the correct
path is /usr/bin/cpp. perlWEB uses the C pre-processor for macro definitions.
2. Some users may be put off at the age of perlWEB. Please don't be!
While originally written in 1997 they system is very stable and is
holding up quite well.
Here is the link for the
perlWEB homepage.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.