Version française
Home     About     Download     Resources     Contact us    
Browse thread
Stricter version of #use ?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Harrison, John R <john.r.harrison@i...>
Subject: RE: Stricter version of #use ?
Hi Zheng,

| You may try the following code snippet. It's not a total solution
| but an ad-hoc workaround. It only deals with recursive "#use" like
| in your example (e.g., "#load" operation inside a "#use" script
| will still behave the same as before), though it's not difficult
| to adapt the other primitives similarly ("#load" is probably the
| only one wanted, let me know if you need any help on that).

Thanks, that's a clever solution! Just one more question, though. I'd
like to exploit this alternative "use" function in a slightly more
programmatic way so I also want it as an OCaml function. (Then I can
search non-standard paths, do basic conditional loading etc.) So I
adapted your solution slightly and put the following in my .ocamlinit
file to give myself a function "use_file" that (so I thought) would
correspond to the #use directive:

  let use_file =
    let is_top = ref true in
    fun name ->
      let top_env = !is_top in
      is_top := false;
      let succ = Toploop.use_file Format.std_formatter name in
      is_top := top_env;
      if not !is_top && not succ then
        (Format.print_string("Error in included file "^name);
         Format.print_newline();
         raise Exit)
      else ();;
  
  Hashtbl.replace Toploop.directive_table "use"
    (Toploop.Directive_string use_file);;
  
So with my "root.ml" and "branch.ml" files from the first message, it
all works exactly as I wanted, a nice early failure with a clear
"traceback":

  # #use "root.ml";;
  val x : int = 1
  val u : int = 3
  Exception: Failure "X".
  Error in included file branch.ml
  # x;;
  - : int = 1
  # u;;
  - : int = 3

Yet if I replace the line

  #use "branch.ml";;

in "root.ml" with what I supposed would be equivalent:

  use_file "branch.ml";;

then the exception propagates out and I get the "rollback" that
I wanted to avoid:

  # #use "root.ml";;
  val x : int = 1
  val u : int = 3
  Exception: Failure "X".
  Error in included file branch.ml
  Exception: Pervasives.Exit.
  # x;;
  - : int = 1
  # u;;
  Unbound value u

Any idea why that should be?

John.