IMP logo
IMP Manual  for IMP version 2.16.0
gotchas.md
1 %IMP gotchas {#gotchas}
2 ============
3 
4 Below are suggestions prompted by bugs found in code submitted to %IMP.
5 
6 - Never use '`using namespace`' outside of a function; instead
7  explicitly provide the namespace. (This avoids namespace pollution, and
8  removes any ambiguity.)
9 
10 - Never use the preprocessor to define constants. Use `const`
11  variables instead. Preprocessor symbols don't have scope or type
12  and so can have unexpected effects.
13 
14 - Don't expect IMP::Object::get_name() names to be unique; they
15  are there for human viewing. If you need a unique identifier
16  associated with an object or non-geometric value, just use the
17  object or value itself.
18 
19 - Pass other objects by value or by `const &` (if the object is
20  large) and store copies of them.
21 
22 - Never expose member variables in an object which has
23  methods. All such member variables should be private.
24 
25 - Don't derive a class from another class simply to reuse some
26  code that the base class provides - only do so if your derived
27  class could make sense when cast to the base class. As above,
28  reuse existing code by pulling it into a function.
29 
30 - Clearly mark any file that is created by a script so that other
31  people know to edit the original file.
32 
33 - Always return a `const` value or `const` reference if you are not
34  providing write access. Returning a `const` copy means the
35  compiler will report an error if the caller tries to modify the
36  return value without creating a copy of it.
37 
38 - Include files from the local module first, then files from
39  other %IMP modules and finally outside includes. This
40  makes any dependencies in your code obvious, and by including
41  standard headers *after* %IMP headers, any missing includes in the
42  headers themselves show up early (rather than being masked by
43  other headers you include).
44 
45  #include <IMP/mymodule/mymodule_exports.h>
46  #include <IMP/mymodule/MyRestraint.h>
47  #include <IMP/Restraint.h>
48  #include <vector>
49 
50 - Use `double` variables for all computational intermediates.
51 
52 - Avoid using nested classes in the API as SWIG can't wrap them
53  properly. If you must use use nested classes, you will have to
54  do more work to provide a Python interface to your code.
55 
56 
57 - Delay initialization of keys until they are actually needed
58  (since all initialized keys take up memory within each particle,
59  more or less). The best way to do this is to have them be static
60  variables in a static function:
61 
62  FloatKey get_my_float_key() {
63  static FloatKey k("hello");
64  return k;
65  }
66 
67 - One is the almost always the right number:
68  - Information should be stored in exactly one
69  place. Duplicated information easily gets out of sync.
70  - A given piece of code should only appear once. Do not copy,
71  paste and modify to create new functionality. Instead,
72  figure out a way to reuse the existing code by pulling it
73  into an internal function and adding extra parameters. If
74  you don't, when you find bugs, you won't remember to fix
75  them in all the copies of the code.
76  - There should be exactly one way to represent any particular
77  state. If there is more than one way, anyone who writes
78  library code which uses that type of state has to handle all
79  ways. For %example, there is only one scheme for
80  representing proteins, namely the IMP::atom::Hierarchy.
81  - Each class/method should do exactly one thing. The presence
82  of arguments which dramatically change the behavior of the
83  class/method is a sign that it should be split. Splitting
84  it can make the code simpler, expose the common code for
85  others to use and make it harder to make mistakes by
86  getting the mode flag wrong.
87  - Methods should take at most one argument of each type (and
88  ideally only one argument). If there are several arguments
89  of the same types (eg two different `double` parameters) it is
90  easy for a user to mix up the order of arguments and the compiler will
91  not complain. `int` and `double` count as
92  equivalent types for this rule since the compiler will
93  transparently convert an `int` into a `double.`
void report(std::string benchmark, std::string algorithm, double time, double check)
Key< 0 > FloatKey
std::ostream & show(Hierarchy h, std::ostream &out=std::cout)