Coding Standards
(Updated for Dakar by
CrawfordCurrie - 16 Feb 2005)
Perl coding standards
System Requirements
Core code should be based on the
TWikiSystemRequirements.
Avoid adding dependencies on external Perl modules not shipped with standard Perl. This is because TWiki is sometimes used in intranet environments where Internet access is difficult or non-existent, making it hard to install add-on modules directly from
CPAN
. Also, someone installing TWiki is often not the server administrator, requiring someone else to perform the module installation (or a more complex
CPAN configuration) - this applies to intranets and
TWikiOnWebHostingSites. You can check which modules are available in which perl releases by looking at the
perl module on
CPAN.
If you find you do have to add a dependency from core code on an external perl module, make sure it is discussed to death on Codev first.
TWiki Coding Conventions
Please follow these coding conventions when contributing to core code. This is to make source code more consistent and readable. Please provide your feedback in
CodingStandardsDiscussions.
Note: the general rule is that readable code is more important than slavish adherence to coding standards. The format of the POD headers for exported functions is important, though, as they are automatically extracted to form the source code documentation in the release.
-
use strict
-
use warnings
-
use Assert
- This defines ASSERT, a function that causes a
die if a condition is false. ASSERT is used as follows: ASSERT( $condition ) if DEBUG; This is conditionally compiled i.e. is enabled only during development.
- Function names:
- Use bumpy words that start with lower case, i.e.
sillyOperation
- Prepend private function names with
_, i.e. _secretOperation
- Function documentation:
- Use the documentation templates below for header documentation for functions.
- Variable names:
- Use bumpy words that start with lower case, i.e.
$sillyVariable
- Always initialize, even if it's to
undef.
- Avoid global variables like the plague, to avoid problems with mod_perl
- White space:
- Follow the style of the current Perl scripts for indentation (four characters per level of indent), spacing around brackets and placement of braces (e.g. of '{}')
- Use only spaces for indent, don't use tabs. Mixing tabs and spaces often causes problems, especially with patches. To simplify doing this with specific editors, see VimEditor, EmacsEditor, ...
- Comments:
- Use comments to describe what you are doing where appropriate
- Special comments: In case some parts of your code need later attention, state that in your comments as:
-
# SMELL: for unclean code that looks like a bug, or violates common coding practices, or misses some corner case
Example package header
=pod
---+ package TWiki::Vector
Objects of this type represent 3D vectors
SMELL: quaternions are more flexible
=cut
package TWiki::Vector;
Example Class Method
A class method is an OO static method that is invoked using indirection off the package object e.g.
TWiki::Vector->new() or
new TWiki::Vector()
=pod
---++ ClassMethod new( $x, $y, $z )
Constructor for a new vector object
* =$x= - X component
* =$y= - Y component
* =$z= - Z component
=cut
sub new {
my( $class, $x, $y, $z ) = @_;
my $this = bless( {}, $class );
$this->{x} = $x; $this->{y} = $y; $this->{z} = $z;
return $this;
}
Note how $class is
not listed in the parameter documentation.
Example Object Method
An object method is a OO method that is invoked using indirection off a blessed object of the package type e.g.
my $c = new TWiki::Coord(1,2,3); $c->normalise(); or
TWiki::Coord::normalise( $c )
=pod
---++ ObjectMethod normalise() -> $length
Normalise the vector to have length 1 i.e. become a direction vector.
Return the magnitude of the original vector.
=cut
sub normalise {
my( $this ) = @_;
ASSERT( $this->isa("TWiki::Vector") ); # it is always best to make sure....
my $mag = sqrt( $this->{x} * $this->{x} + $this->{y} * $this->{y} + $this->{z} * $this->{z} );
$this->{x} /= $mag; $this->{y} /= $mag; $this->{z} /= $mag;
return $mag;
}
Note how $this is
not listed in the parameter documentation.
Example exported static method
Header for a static method intended to be visible outside the package. A static method is any non-OO method.
=pod
---++ StaticMethod dot( $vectorObject, $vectorObject ) -> $number
Return the dot-product of two vectors.
=cut
sub dot {
my ( $a, $b ) = @_;
ASSERT( $a->isa( "TWiki::Vector" )) if DEBUG;
ASSERT( $b->isa( "TWiki::Vector" )) if DEBUG;
return $a->{x} * $b->{x} + $a->Py} * $b->{y} + $a->{z} * $b->{z};
}
Private methods
headers for private methods (private class methods, static methods and object methods) should follow the same pattern as exported methods except that they should be documented using # comments rather than POD. For example,
# ---++ ObjectMethod _crush( \@x ) -> $boolean
# Crush the vector with an array.
# Note use of \@ to indicate an array reference
# Note also use of $boolean to indicate the result type.
# Remember that undef, "" and 0 are all FALSE in perl, and any non-zero number or non-empty string is TRUE.
sub _crush {
my( $this, $x ) = @_;
ASSERT( ref($this) eq "TWiki::Vector" );
...
Internationalisation support (
)
See:
InternationalisationGuidelines
You don't need to know anything about internationalisation (
I18N) to make your code work with international characters in
WikiWords and much more, and it also makes your code more readable. The guidelines cover both core code and plugins.
Tool Support
Options to ensure consistent formatting:
CSS coding standards
See:
CssCodingStandards
JavaScript coding standards
See:
JavaScriptCodingStandards
See also
CodingGuidelinesFromElsewhere