caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "Nicolas Pouillard" <nicolas.pouillard@inria.fr>
To: "Till Varoquaux" <till.varoquaux@gmail.com>
Cc: "Jonathan Roewen" <jonathan.roewen@gmail.com>,
	OCaml <caml-list@yquem.inria.fr>
Subject: Re: [Caml-list] A global exception handler...
Date: Thu, 6 Jul 2006 17:25:57 +0200	[thread overview]
Message-ID: <cd67f63a0607060825h7e701760uf10102c0a9233df2@mail.gmail.com> (raw)
In-Reply-To: <9d3ec8300607060748s18ad08c6v282af9bc795099c8@mail.gmail.com>

On 7/6/06, Till Varoquaux <till.varoquaux@gmail.com> wrote:
> On 7/6/06, Jonathan Roewen <jonathan.roewen@gmail.com> wrote:
> > Hi,
> >
> > Is it possible to register a global exception handler?
> >
> > I suppose I could just nest everything inside one giant function if I
> > really had to, but I like my toplevel expressions ;-)
> >
> CamlP4 might come in handy here. I'm guessing you could rewrite your
> program so that all your toplevel expressions are in one main ()
> function using camlp4. It would have some limitations though: for
> instance your exception handler could not use anything defined in main
> (unless you where using references). I'm guessing it's not so bad
> because whatever happens you cannot have a global exception handler
> relying to much on stuff defined in your programm.

Here is a simple Camlp4 filter that written for the new Camlp4 version (CVS) :

$ cat global_handler.ml
open Camlp4.PreCast;

value ghost = Loc.ghost;

value global_handler_ref = ref <:expr@ghost<>>;

value find_global_handler = object
  inherit Ast.map as super;
  method str_item st = do {
    match st with
    [ <:str_item< value global_handler = $f$ >> -> global_handler_ref.val := f
    | _ -> () ];
    super#str_item st
  };
end;

AstFilters.register_str_item_filter
  (fun st ->
    let _ = find_global_handler#str_item st in
    <:str_item@ghost< try let module Main = struct $st$ end in ()
                      with e -> $global_handler_ref.val$ e >>);

$ ocamlc -I +camlp4 -c -pp camlp4rf global_handler.ml

$ cat global_handler_test.ml
open Format;;
let f1 x = printf "f1 %d@." x;;
let f2 x = printf "f2 %f@." x;;
let f3 x = printf "f3 %s@." x;;
f1 1;;
f2 1.1;;
f3 "1.1.1";;
raise (Failure "test");;
let global_handler e =
  (* Note that I need to give the complete name for eprintf since
     Format is not opened in the new environment of global_handler. *)
  Format.eprintf "global_handler: %s@." (Printexc.to_string e)

$ ocamlc -pp 'camlp4o global_handler.cmo' global_handler_test.ml

$ ./a.out
f1 1
f2 1.100000
f3 1.1.1
global_handler: Failure("test")

$ camlp4o global_handler.cmo -printer OCaml global_handler_test.ml
try
  let module Main =
    struct
      open Format
      let f1 x = printf "f1 %d@." x
      let f2 x = printf "f2 %f@." x
      let f3 x = printf "f3 %s@." x
      let _ = f1 1
      let _ = f2 1.1
      let _ = f3 "1.1.1"
      let _ = raise (Failure "test")
      let global_handler e =
        (* Note that I need to give the complete name for eprintf since
     Format is not opened in the new environment of global_handler. *)
        Format.eprintf "global_handler: %s@." (Printexc.to_string e)
    end
  in ()
with
| e ->
    (fun e -> Format.eprintf "global_handler: %s@." (Printexc.to_string e)) e

Cheers,

-- 
Nicolas Pouillard


  reply	other threads:[~2006-07-06 15:25 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-07-06 14:39 Jonathan Roewen
2006-07-06 14:48 ` Till Varoquaux
2006-07-06 15:25   ` Nicolas Pouillard [this message]
2006-07-06 15:33     ` Jonathan Roewen
2006-07-06 15:37       ` Nicolas Pouillard
2006-07-06 15:39         ` Jonathan Roewen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cd67f63a0607060825h7e701760uf10102c0a9233df2@mail.gmail.com \
    --to=nicolas.pouillard@inria.fr \
    --cc=caml-list@yquem.inria.fr \
    --cc=jonathan.roewen@gmail.com \
    --cc=till.varoquaux@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).