Reputation: 11258
The following code...
type 'a osResult =
Success of 'a
| Error of string
let errorCatcher f =
try
let result = f () in
Success result
with Unix.Unix_error (code, fun_name, arg) ->
Error(String.concat ":" [(Unix.error_message code); fun_name; arg])
let my_getcwd () =
errorCatcher (fun () -> Unix.getcwd ())
let _ =
print_endline "The Start";
let result = my_getcwd () |> function
| Success folder -> Printf.sprintf "getcwd:\n\t%s\n" folder
| Error errMessage -> Printf.sprintf "getcwd (error):\n\t%s\n" errMessage
in
print_string result ;
print_endline "The End."
;;
...compiles fine:
$ corebuild -tag debug test1.native
...and runs fine:
$ ./test1.native
The Start
getcwd:
/home/ttsiod/work/byePythonHelloOCaml
The End.
But if I change the main body to this:
let _ =
print_endline "The Start";
my_getcwd () |> function
| Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
| Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
;
print_endline "The End."
;;
... then apparently the last print statement ("The End") gets lost or something...
$ ./test2.native
The Start
getcwd:
/home/ttsiod/work/byePythonHelloOCaml
Initially, I thought this is a case of stdout buffering not being flushed.
But the docs of print_endline
clearly claim that it flushes stdout, so I am at a loss - and adding "flush" didn't help, either:
let _ =
print_endline "The Start";
my_getcwd () |> function
| Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
| Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
;
print_endline "The End." ;
flush stdout
;;
Help?
Upvotes: 1
Views: 2597
Reputation: 7196
The print_endline
is treated as part of the Error
case. From the indentation, this is clearly not what you meant, but unfortunately the OCaml compiler doesn't warn about this.
You can use begin
and end
(or just parentheses) to make it work:
let () =
print_endline "The Start";
my_getcwd () |> begin function
| Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
| Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
end;
print_endline "The End." ;
flush stdout
Alternatively, without using ;
,
let () =
let () = print_endline "The Start" in
let () = match my_getcwd () with
| Success folder -> Printf.printf "getcwd:\n\t%s\n" folder
| Error errMessage -> Printf.printf "getcwd (error):\n\t%s\n" errMessage
in
let () = print_endline "The End." in
flush stdout
Upvotes: 3