Hi,
I like it. It's informal, but that's ok because it's made
for a one man show. Plus it has some things I never thought of that are just smart. Big ++ from me.
Oh. And here's something from our PPCGs (PetaMem Perl COding Guidelines):
These are made to be aplicable for a group of programmers, with bits from other styleguides shamelessly stolen and even containing some totalitary guides like "you have to program with that editor". But I think this totalitarism is needed if you need to keep a Perl development team in sync.
- Why PPCG? Why English?
First off, be assured, that other programmers *will* have to read
your code. This can be in one or in two years, or in a week. Be
also assured, that YOU will have to read your own code in a year or
so. The other programmers reading your code may not speak czech,
german, hindi or esperanto, but they certainly will speak and
understand english. That's why all development has to happen in
this language.
- english documentation
- english remarks in the program
- english variable, package, symbol, subroutine ... names
- Choose the right editor - it can help your career!
Basically you may choose whatever editor you like. If you don't
choose emacs - however - you have to make pretty sure, that your
source code is not screwed up in emacs. Why? Because the pointy
haired big boss (PHBB) is using emacs and wants to use emacs and he
will review all of your code in this editor. And because you'll
see, that there are more requirements to a PetaMem sourcecode, that
only few editors are able to meet.
If you to a later point want to be promoted to some "inferior big
boss" position and review the code of some PetaMem programmers, you
must do this in emacs. Why? Because even as an "inferior big boss"
it can happen to you, that the real PHBB will re-review this
code. If he should find any mistakes in a sourcode aproved by you,
you will be very fast transformed from an "inferior big boss" to a
dishwasher. So emacs can help your career - it cannot guarantee it
however.
Make use of folding at the subsourine/method level. '{{{' is the
start of a fold '}}}' is the end of it. The folding.el module for
emacs does a good job at this. It should look like that:
# {{{ main_init main initialization routine
#
sub main_init {
#
# The priority of configurations is:
# 1. command line parameters
# 2. .elricrc file
# 3. defaults/autodetection
# At every beginning of a block - if you have to declare my variable
+s...
my $cpu = '';
my $get_opt = '';
if(-e '.elricrc') {
$config = ConfigReader::Simple->new(&globalconf('rscfile'));
$config->parse();
$cpu = $config->get('cpu') || &num_cpus;
}
$get_opt = GetOptions('cpu=i', \$cpu,
'c=i', \$cpu,
'help', \&print_usage_cmdline,
'h', \&print_usage_cmdline,
'v', \&print_version);
&print_welcome;
&globalconf('cpu',$cpu);
}
# }}}
Give emacs hints what this source is all about:
# For Emacs: -*- mode:cperl; mode:folding -*-
Yes, use cperl-mode
Don't use nested folds. There are at least two reasons:
- Nested folds are realized using different line ending, so
this source cannot be compiled correctly.
- You've done a mistake in your problem specification and/or
don't write clean and efficient code.
- The absolute basic hints
- Know what the code is supposed to do BEFORE you start
- Don't be too clever. Be elegant when coding and yes - cleverness
is helpfull, but don't be TOO clever making it hard for someone
reviewing your code a year later trying to find out what idea you
had that best day in your life far ago.
"You may think of a very clever way to code something this
week. Unfortunately you may not be as clever next week and you
might not be able to figure out what you did."
- If you want to be especially clever (or need to, because the
problem is hard) use apropriate documentation. Apropriate
documentation is, what all of the rest of the development team
understand (including the PHBB).
- don't mix platform dependent code with platform independent
one. Test your code under various platforms.
- Maintainable code should be your holy grail, above and beyond any
other consideration (except for correctness). It should be more
important than optimization (save for when business needs demand
it).
- PetaMem Specifics
You will use CVS source code and versioning system. Get used to it
and USE it. Don't see the additional information requirements it
puts on you as balast. You will miss that information to a later
point. (Or regret not filling out after a talk with the PHBB)
Every File of your Perl Sourcecode must contain the following
header <xx> are placeholders:
# Started <date> by <name>
#
# $Author$
# $Date$
# $Id$
# $Revision$
#
# [Modified <date> by <name>]*
# <name of the file> <version_of_the_source>
# Sanity checks: VARS|PROF|CERT
#
# PPCG: <version of the PPCG you are coding after>
As for the sanity checks:
VARS: Checked if there are any unnecessary variables
(unused, used only once) and removed them
PROF: Code has been examined and optimized by the help
of the Profiler
CERT: Certify, that this file has been validated against
the stated PPCG
- To work out the design priorities at PetaMem consider the
following priorities for your code:
Prio 1 CORRECT
does what you intended
what you intended was specified
Prio 2 MAINTAINABLE
well structured/modularized
good documented
easy to understand
Prio 3 REUSABLE
generic
Prio 4 EFFICIENT
fast
ressource friendly
small memory footstep etc.
- Efficient being last priority doesn't mean, that you can or
should choose the wrong algorithm O(n) instead of O(log n), or -
to speak mor generally - with a runtime/memory complexity some
level above the optimum solution. It just means, that you don't
need to worry about reimplementing in C immediatedly. If you
encounter a memory/cpu tradeoff situation, going for more memory
instead of hoping for a faster CPU is the way. (most of the time
and even then it depends)
- Before you "finish" your work on a module or logical piece of
code of yours, use Benchmark and the Profiler. See if there are
any bottlenecks and eliminate them. Then your code is
nearly "finished". So far for efficiency.
- Then test it on various platforms and run it through the bytecode
compiler. If it won't work on a platform, find out why and try to
fix it. If fixing doesn't work (without major work), document
it. Same applies to bytecompiling the code. THEN and only after
youve performed all these steps. Your code can be seen as
"finished" - ready for the maintainance mode.
- Use Comments
If your program is not worth documenting, it probably isn't worth
running. The time you save by writing clean code and commenting it
carefully may be your own. Your comments are as important as your
code. The compiler won't see them, but pople will. Be precise,
don't be lenghty. Making speling errors in comments is bad. Have
you forgotten? Comments are important and deserve at least a
proofreading. You will see examples of comments later in the
examples section.
You should use your comments to be easy used by others. It's hard to
read and underestand program code if you must be very carefull to
don't skip some fundamental construction hidden between comment
lines.
It is better to use block of comments describing some action
followed by block of code with described functionality
instead to comment each line of code. If you need to comment each line
place comments at the end of these lines.
Wide acceptable are comment schemes like
comment comment comment comment comment comment comment
comment comment comment comment comment comment comment
comment comment comment comment comment comment comment
code code code code code code code code code code code
code code code code code code code code code code code
code code code code code code code code code code code
code code code code code code code code code code code
code code code code code code code code code code code
or
code code code code comment comment comment
code code code code comment comment comment
code code code code comment comment comment
code code code code comment comment comment
code code code code comment comment comment
code code code code comment comment comment
But not
comment comment comment comment comment comment comment
code code code code code code code code code code code
comment comment comment comment comment comment comment
code code code code code code code code code code code
comment comment comment comment comment comment comment
code code code code code code code code code code code
- Robust Code
- use -w, don't use warnings instead
- use strict
- use Carp
- be robust. Write robust code. That is - your code shouldn't
break. When your code is robust enough, you will realize, that it
is the environment that will break. Don't assume everything will
go ok. Test the return values of the system calls and let
subroutines have intelligent return values that allow you to be
robust. (i.e. end gracefully on fatal errors or - even better -
be that high-level fault tolerant that allows you to continue
alternatively.
Remember: You're working for a company that creates
AI-entities. You don't need to restart your brain when
encountering an error. The AI shouldn't either. The AI may go
down if the machine it is running on explodes. And only then and
only if the machine explodes completedly.
- I said be robust don't be paranoid. Testing the return value of
print is paranoid. (Most of the time)
- Concrete examples for robustness:
- User-Level: Handle wrong inputs or completedly missing
inputs gracefully. In fact, expect them to go wrong.
- System-Level: Expect that system calls may go wrong. Don't die
because of this
- Program-Level: It shouldn't happen, but as we can create
code dynamically @ runtime... Handle missing or wrong parameters
gracefully.
- Hardware-Level. The machine you're running on is or may get
buggy. Have sanity checks. Die gracefully and informative
if you find your context broken.
- General Perl Habits @ PetaMem
- All PetaMem Perl developers are members of perlmonks.org, some
are at the Prague Perlmonks.
- Using Alien Perl Modules
- Use of alien modules (from CPAN) is strongly preffered over the
use of an own reimplementation of some task. Even if the module
may seem an overkill. However: The policy for using modules is,
that first the "best" module for a given task has to be choosen.
Choosing is done by a gremium of at least 2 programmers. These
are commited to do research at various community places like
Perl-Newsgroups or Websites to form and support their
decision. After they've chosen, they have to CARVE their decision
in a document at W3, stating which module was chosen over what
others, when and why.
- Now be very VERY careful what you chose, because: If time shows,
that another module is better (extended/faster functionality) and
should be used instead of the old one, a gremium of at least 2
programmers including the PHBB has to make the decision to
replace the old module against the new one. IF the decision is
made, ALL use of the old module in existing sourcecode has to be
replaced with the new one. Therefore it may well be, that
replacing a modul won't happen even if it is technically
superior. That's a bad thing. PetaMem programs should be that
well written (functional encapsulation) and documented, that a
replacement could happen.
- If a module gets replaced, this decision has to be CARVED in
W3. The information about why we used the old module becomes part
of this report.
- We're a small company (for now). But we're using a powerfull
language and we're moving in a powerfull community. These two
pillars are the giants on whose shoulders we stand. Don't program
it if it already exists. If you do, you're asking for trouble.
- Various suggestions
Interpolation, concatenation and list context
Using interpolation is in many cases a waste of ressources. Interpolation
is absolutedly equivalent (in terms of speed) to concatenation and this is
- when printing - much slower than using list context. This is because print
expects a list context.
"$blah1 $blah2" (INTERPOLATION)
$blah.' '.$blah2 (CONCATENATION)
$blah,' ',$blah2 (LIST CONTEXT)
If you just need to construct a string which you need in scalar
context, you must concatenate. And therefore it is sometimes much
clearer and more readable if you use interpolation.
You may prefer interpolation for readability AND(!) if the operation
doesn't require maximum speed. In every other case use list context.
Code length
If your subroutine is longer than 70 lines of code, you can be sure,
that you're doing something wrong. If it is more than 100 lines you most
probably have done a major mistake in the design of your code and it
needs to be reviewed by someone other.
- Overall module structure
Make your folded module look like this:
# CREATE methods
# {{{ new constructor...
# {{{ read read and parse lexicon from file...
# {{{ restore fast restore of dumped lexicon...
# QUERY methods
# {{{ isin is the $key in this lexicon...
# {{{ info information about the contents of this lexico
+n object...
# MODIFY methods
# {{{ add_entry add entry to lexicon...
# {{{ add_entries add entries to lexicon...
# {{{ add_meaning add meaning IF DISJOINT else DISCARD or REPLA
+CE...
# {{{ del_entries delete entries from lexicon...
# {{{ merge merge some other lexicon to this one...
# {{{ consolidate consolidate this lexicon...
# {{{ dump dump lexicon for fast recovery...
# DERIVE methods
# {{{ expand expand one entry...
- To be continued...
signed
the PHBB & Co.
|
Bye
PetaMem
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|
|