I have several modules implementing the same interface. I want to load only one of this module depending on one argument given on the command line.
I was thinking to use first-class module but the problem is that I want to execute some functions before that the module is instanciated.
For the moment I have this :
module Arch = (val RetrolixAbstractArch.get_arch() : RetrolixAbstractArch.AbstractArch)
let get_arch () =
let arch = Options.get_arch() in
if arch = "" then
Error.global_error "During analysis of compiler's architecture"
"No architecture specified"
else
if arch = "mips" then
( module MipsArch : AbstractArch)
else
Error.global_error "During analysis of compiler's architecture"
(Printf.sprintf "Architecture %s not supported or unknown" arch)
But since the command line is not parsed yet, Options.get_arch give me the empty string.
I would like to realize the command line parsing before that this function is executed (without adding the parssing in the function). Is it possible ? Should I find an other way to achieve this ?
It is possible, but you must use local modules. This is a minor issue, that basically requires only few refactoring.
Another approach is to functorize your modules with arch structure and instantiate your functors as soon as you know the architecture. You can see a full fledged example here (see function
target_of_archthat creates first-class module for particular architecture).If your
AbstractArchinterface doesn't contain type definitions, then you can use other abstractions instead of modules: records of functions or objects. They may work more smoothly, and may even allow you to overload the arch instance dynamically (by making thearchinstance to be a reference, although I wouldn't suggest this, as it is quite unclean, imo).