Reputation: 629
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 ?
Upvotes: 3
Views: 730
Reputation: 35280
It is possible, but you must use local modules. This is a minor issue, that basically requires only few refactoring.
let arch_of_name = function
| "mips" -> (module MipsArch : AbstractArch)
| "arm" -> (module Arm)
| _ -> invalid_arg "unknown arch"
let main () =
...
let arch_name = get_arch () in
let module Arch = (val arch_of_name arch_name) in
(* here you can use module Arch as usual *)
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_arch
that creates first-class module for particular architecture).
If your AbstractArch
interface 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 the arch
instance to be a reference, although I wouldn't suggest this, as it is quite unclean, imo).
Upvotes: 9