view doc/policies.txt @ 12:bff0d802cb7d

Implemented some internationalization support. Implemented i18n.I18nTranslation class to load strings and descriptions from files (with unittest). MTUnknownTypeException removed: its pointless since it's always ignored without even any message. A few fixes to mde.mergetag.read.Reader regarding partial reading. committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Fri, 22 Feb 2008 11:52:20 +0000
parents 4c3575400769
children
line wrap: on
line source

This is a collection of all coding policies for the mde engine as a whole. Policies for individual packages should be put in the individual package directory or elsewhere.

These are principles, not cast-iron rules, which I (Diggory Hardy) generally try to adhere to. If any other programmers have better principles to apply over these rules, they may do so for their own coding providing they have a good reason (i.e. not simply wanting to be a little different).

A warning: I have several times changed my mind about items I've written here. So don't expect all existing code to conform, and if you feel that a principle listed is not a good idea don't think you have to conform to it.



Coding conventions: Mostly stick to those provided in the D specification. Generally indent with four spaces and use tabs to align comments. Keep editor's tab-width at 8. Aim to break long lines at around 100 chars (particularly with documentation); this isn't essential but provides a good guide and keeps text looking reasonable. With code, however, breaking lines doesn't always produce better-looking code.

Identifiers: as for the D spec, use descriptive words for identifiers, although try to keep them from being overlong. Use capital letters to show separate words, not _s. E.g.: file, readFile; not: rdFile, read_file, readFileUsingMyMethodNow. Again, this is only really a guideline.

Module/file names: unless you have a good reason, keep names all lower-case. And if you're programming on windows, make sure you always use the correct capitalisation (yeah, of course...).

Spelling (within code): Use whichever spellings you like (so long as it's good English), but use these spellings consistantly, at least for code symbols within packages (i.e. if you write your own package you can choose the spellings, and for comments it doesn't really matter, unless it's actually refering to a symbol).



Package design principle: use a separate package for each module of the engine. In most packages where there is only one module (file) imported by other parts of the engine, that module should have the same name as the package and be designed to have a standardised interface to the package so that the package could be replaced with another as a drop-in replacement (written with the same interface). Of course in many cases it may not be possible to swich one package for another quite this easily, but holding to this principle should at least minimise the amount of work necessary when doing so.


Module imports: modules should publically import dependancy modules likely to be needed by dependant modules, in particular the package-level exception module (where used & use by dependants is expected).


Engine-wide initialisation and cleanup should be handled or invoked by mde.init.Init's CTOR and DTOR methods where this is viable.



Unittests (last block in the module where multiple unittest blocks are used) should end with:
    logger.info ("Unittest complete.");
No more logging should be needed, since if it fails whoever runs the unittest will know about it, and logging messages cannot be used to tell how complete the unittesting is. These messages just confirm that the unittests ran really.

Unittests may be defined in their own modules or other modules. Unittests should be wrapped in
    debug(mdeUnitTest)
statements (these may also be used to wrap imports only needed by the unittest). Any modules containing unittests should be imported by test.mdeTest.



Logging should be handled by tango's Logger class. A logger with the name mde.package.module or mde.package.module.X where X is a symbol within the module should be used for each module. Thrown errors should, where documented, be documented with a log message; an exception message may be used to produce the final log message but must be output via a log message.

In general the levels should be used as follows:
	Trace	Where required or thought highly useful for debugging, and only compiled in debugging mode.
	Info	Sparingly, for informational purposes (e.g. when parsing a file). Should not generally be used repetitively (within loops, etc.). Not for reporting unexpected behaviour.
	Warn	For small errors which can be overlooked, even if they MAY cause bigger problems later. I.e. something unexpected, but not necessarily a major problem, happens.
	Error	For errors which directly:
		• cut-short a (reasonably large) operation (e.g. reading a file).
		• cause a significant change in program operation, but do not directly cause the program to terminate.
	Fatal	For errors directly (i.e. definately and almost immediately) ending the program.

For all levels bar trace, messages should if possible be understandable to end users, while (for warn and above) including enough information to fix the problem, including code symbols if necessary.
Thus:
	Trace output should only be available when compiled in debug mode.
	When run by an end-user (with info-level logging enabled),
	• info messages normally occur and should be understandable to end users;
	• warn messages may occur, and may or may not indicate problems;
	• error messages indicate that something big is wrong, and if the program still runs it is unlikely to be usable as intended;
	• fatal messages indicate a problem preventing the program from running.


Thrown errors should use an exception class specific to at least the package involved to enable specific catching of errors. Exception classes should be defined within a module exception.d in the package directory. Exception classes should generally follow the conventions within mde/exception.d to aid in providing reasonable error messages.


Log/exception messages should be in English. They should include a brief description, but do not need a long description since the message can be looked up in the code. Currently there is no plan for translating log messages, however if someone wants to implement I18nTranslation to provide the messages they can.



User output (internationalization support): i18n.I18nTranslation is designed to fetch a full string and optionally an associated descripion given an identifier. The identifier may also be a code symbol, and should be brief, in English, and give at least some idea of its meaning, since if no translation is available the identifier will be output. For example:  "example message" or "exampleMessage", not "An example of a message". For any new entry created, at least one full entry should be added to the i18n database for some form of English so that:
    (a) there is something available to translate to other locales
    (b) English developers can understand what it means