Saroupille
Saroupille

Reputation: 629

Instantiate a module in OCaml dynamically

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

Answers (1)

ivg
ivg

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

Related Questions