Skip to content
Andrew Lambert edited this page Jun 7, 2017 · 17 revisions
  1. All code must be compatible with REALstudio 2011r4.3, or use conditional compilation around language features introduced after that version.

  2. A subclass implements a superset of the parent class functionality, not a subset. Refused Bequests are forbidden.

  3. Variable, class, and method names should be unabbreviated, correctly-spelled, and given in SentenceCase. Prefixes and suffixes (i.e. Hungarian notation) are not allowed. Underscores and non-ASCII characters should be avoided.

  4. Names of constants should be in CONSTANT_CASE: all uppercase letters, with words separated by underscores.

  5. If a method performs an action then the method name should include the action name; methods themselves should be written such that their entire purpose can be summed up in one or two words (i.e. the method name) plus the names and types of the parameters and return value. This does not mean that names should be phrases describing the method: CreateOrOpenFileAndMoveToEnd(Path As String) is bad ; OpenFile(Path As String, Create As Boolean, Position As Integer) is good.

  6. Callback methods must explicitly declare their calling convention, even if it's not required.

  7. Callback methods must not raise or propagate runtime exceptions (more specifically, exceptions must not cross foreign stack frames.) Instead callbacks should return an appropriate libcURL error code to signal an unhandled exception.

  8. All classes have at least one Constructor method (which need not be Public.) Foo.Constructor() always creates a brand new instance of Foo. Foo.Constructor(Foo) always creates a new instance of Foo that duplicates the characteristics of the instance of Foo that is passed as an argument. Any other Constructors create a new instance of Foo using the characteristics specified by the arguments.

  9. The lexical scope of any method, variable, constant, etc. shall default to private. It can only be promoted to protected if you have a reason, and to public if your reason is good. Global scope requires a damned good reason. Destructor methods are always private.

  10. Introspection shall not be used to violate lexical scope, for example modifying a private variable from outside its class. In general do not use Introspection when alternatives exist.

  11. If a class has many Constructor methods, you should consider changing some of them into shared methods with more meaningful names.

  12. All variables, etc. should organized in the narrowest possible logical scope. For example, a method that operates on a class should be defined in that class rather than in some "helpers" module.

  13. "Helpers" modules are forbidden except as private submodules (i.e., inaccessible to users.)

  14. Operator_Convert() As PRIMITIVE is forbidden. "PRIMITIVE" means any type that is not a class, array, structure, or enum.

  15. Use standard RB/Xojo capitalization and formatting. Select a block of code in the IDE, right click on it, and then choose "Standardize format".

  16. The loop variable in a For loop should be declared within the For statement unless the variable should exist outside of the loop's scope.

  17. The IsA operator shall be used only to determine the type of Variants and WeakRefs. It may not be used to distinguish a subclass from a superclass. The Is operator shall be used only to test for Nil in an Operator_Compare method.

  18. The RaiseEvent keyword is mandatory, even when not needed to disambiguate an event from a method of the same name.

  19. External methods (AKA "declares") should be private members of a module. Inline declares are discouraged.

  20. Methods that deallocate a resource should be idempotent, meaning that calling them twice (or more) on the same resource has exactly the same effect as calling them once. This includes Destructor methods, as well as any intermediary deallocation methods (e.g. Close()).

Clone this wiki locally