Multiple Trunks in Associated OCaml Modules

I have several “library” modules in OCaml (mainly utility and auxiliary functions), where I added the following code at the end for trivial unit testing:

let main () = ... main 

or

 let () = ... 

This is code that mostly prints to the console (for simple testing purposes). The problem is that when I link my “library” modules to my “main” module and execute the program, I get all these distracting test messages. Is there a way to include code in the OCaml module, which runs when the module is connected alone (thereby facilitating trivial testing), but not when used as a "library"? I read posts in SO that OCaml has no concept of a “main” module and that all modules are equal, however it seems to me that the order of the object files provided to the linker can be interpreted to indicate that the last module is “main” ( because it’s at the top of the “food chain of dependencies”).

+7
source share
2 answers

OCaml supports static linking and dynamic module loading; what you usually do (and what a safe type is) is static binding. I would recommend only dynamic loading if you need some kind of plugin architecture.

In any case, a library is nothing more than a module (possibly with submodules). If you statically link a module, all the "main" routines will be executed in the order of the modules in your executable.

So, if you are not doing anything, the module does not know which executable file it is connected in any “magic” way; what you should do is:

  • move tests from modules, perhaps using ounit OR
  • at least rewrite your test functions as real functions, for example. "let test () = ..."; then write a test interface that will call all the "test" functions from all of your modules.

Application:

If you do this in other languages, then there seems to be no free cake:

In Java, if there are several network components in the code, you must explicitly choose the one you want to run the executable file.

In C, you can use the C preprocessor to do something like

 #ifdef TEST_1 int main() { ... } #endif 

OCaml has its own camlp4 preprocessor ( camlp4 wikipedia article ), with which you could do something like this. I personally think that such a test implementation is bad programming. You better check your module / class / .. from the interface side and mark your internal invariants with statements (which exist in Java, C and OCaml).

+7
source

There are no conditions for this in the toolchain; it creates a file that runs the top-level code of all modules at startup, in linking order.

I do not see how to make it work systematically. Modules almost always have top-level code that needs to be executed. You would need to split the top-level code into two groups (one group was always executed, and the other was executed only when the module was the last connected). It seems overly dirty.

The best solution (it seems to me) is just a slightly more complex testing framework.

+5
source

All Articles