Copyright © 2003, 2004, 2005 Interchange Development Group
This documentation is free; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Abstract
The purpose of this document is to present the officially encouraged Interchange programming style.
Table of Contents
Interchange programming style is perlstyle
, with few
additions. Most of the following was decided in a meeting held on
November 14, 2000.
We agreed that it is good to have a programming style, and that the existing style of code should be preserved. We agreed that making global changes to impose a consistent style is not worth doing. Instead, we will make revisions as we rewrite code. We will generally follow the published Perl style guidelines.
if / else - we accept, but do not
encourage the use of cuddled else constructs
(those with } else {
on the same line). Use:
} else {
Lexical Issues - white space is free,
and white space around operators increases readability.
Lining up equal signs (=
) in a series of assignments can be
used to emphasize the parallel structure.
reset_calc() unless $Vend::Calc_reset;
$CGI_array = \%CGI::values_array;
$CGI = \%CGI::values;
$Carts = $::Carts;
$Items = $Vend::Items;
Naming - package globals
should start with a capital letter. In other
situations, avoid StudlyCaps where names begin
with a capital letter.
Items in the main package should be referenced as
$::
, not
Foo
$main::
.
Foo
## Allow no substitution of downloads return if $::Pragma->{download};
Filehandles - Use lexical variables (added in 2008):
# BAD open SRC, $assertfile # GOOD open my $src, $assertfile
Return from subroutines - Use explicit return
statements.
Globals - global variables and subs
should be used very sparingly.
Occasionally it is necessary to use global variables as implicit arguments
to certain subs for efficiency purposes. We should not add more globals,
and we should consider removing existing ones. An important exception are
certain subs such as logGlobal
,
logDebug
, errmsg
, and
logError
.
CVS - CVS comments should be meaningful. As a matter of good programming practice, we encourage a careful review of all diffs before committing changes to CVS. When committing a large number of files (possibly containing changes and fixes to multiple areas) it is best to create file-specific comments addressing individual fixes. Using blank comments is not encouraged.
Loops - we prefer to declare loop control variables immediately prior to the beginning of the loop:
my $var; foreach $var () { ... }
HTML - in late 2004, it was agreed to make the HTML code as XHTML-compliant as possible, but without using XHTML constructs that could cause problems for older browsers. (This subset of support should also be common to HTML).
In essence, all HTML tag and argument names should be lowercased,
and all argument values should be quoted, using double quotes if not
particularly unsuitable. Perl gives us the nice qq{}
operator that eliminates the problem of quotes clashing with Perl syntax:
my $buf = qq{<a href="http://www.av.com/">Visit AltaVista!</a>};
XHTML also mandates that all
tags are treated as containers. This is easy to follow for container tags
such as <p> — simply remember not to omit the closing tag.
With non-container tags, such as <input>, <br> or <hr>,
closing >
needs to be replaced with
/>
, but not unconditionally (Interchange must be able to
output both the usual > and and XHTML variant />).
In such constructs, you can use $Vend::Xtrailer
that's automatically set to /
if XHTML
is
enabled, and eventually you could replace your "raw" calls to tags
such as <input> with calls to Interchange tags formel
or display
that will honor $Vend::Xtrailer
.
<form action="[process]"> <input type="text" name="city" value="[value city]" /> <input type="submit" value=" Submit " /> </form>
See usertag and ITL glossary entries and the
UserTag
configuration directive for technical information.
If you use addAttr
option, then name the
hash-receiving variable "$opt
":
UserTag test Order one two three UserTag test addAttr UserTag test Routine <<EOR sub { my ($one, $two, $three, $opt) = @_; .... } EOR
As you might know, XMLDOCS documentation system contains
bin/stattree
script which parses complete Interchange
source tree. Even though it really tries to recognize code regardless
of formatting (much like Perl interpreter does), there are still some
little suggestions on the programming style to make it easier for XMLDOCS.
Do not use the hash character #
in weird contexts.
Use it only for comments (putting a space between eventual code and inline
comment) or simple substitution such as s#A#B#g
.
(Impact: cosmetic)
# Line comment my $test = 12; # Only used for test
Do not break word sub
and subroutine name to separate
lines.
sub test....
is OK, sub \n test
is NOT.
It's best to use the cleanest variant that matches regular expression
^sub \w+ {$
.
(Impact: might confuse function tracking code)
sub test1 {
Do not break obviously "solid" blocks of code to multiple lines. To give
you an idea of what I am talking about, let's say you should not break
typical xmldocs regexps, such as /\$::Pragma->{(\w+?)}/
or /\$Vend::Cfg->{Pragma}{(\w+?)}/
. (Impact: important. Might prevent the bin/stattree
script from detecting symbols)
return if $::Pragma->{download}; if ( $Vend::Cfg->{Pragma}{download} ) {
Do not break blocks of code that obviously follow a lexical pattern. For example, do not introduce double quotes or structural changes to the below:
['FormAction', 'action', ''],
['MaxServers', 'integer', 10],
['GlobalSub', 'subroutine', ''],
['Database', 'database', ''],
['FullUrl', 'yesno', 'No'],
['Locale', 'locale', ''],
['HitCount', 'yesno', 'No'],
['IpHead', 'yesno', 'No'],
['IpQuad', 'integer', '1'],
['TagDir', 'root_dir_array', 'code'],