Create a folder called myutility, with a Makefile, as well as
a src subfolder:
mkdir ~/myutility
cd myutility
touch Makefile
mkdir src
Inside src, make an interface file called utils.mli
(** A collection of basic utilities. *)
val try_finalize : ('a -> 'b) -> 'a -> ('c -> 'd) -> 'c -> 'b
(** Run a finalizer before returning a result or raising an exception.
For example:
[try_finalize open_file "myfile.txt" close_file "myfile.txt"]
This runs [open_file "myfile.txt"], then [close_file "myfile.txt"]
before returning the result. If [open_file "myfile.txt"] raises an
exception [exn], [try_finalize] will catch [exn], and run
[close_file "myfile.txt"] before re-raising [exn]. *)
Now create an implementation at src/utils.ml:
(** Implementation of the Utils module. *)
(** Run [f x], then [finally y] before returning/raising. *)
let try_finalize f x finally y =
let result =
try f x
with exn ->
finally y;
raise exn
in
finally y;
result
Now create a src/main.ml file:
open Unix
let do_something () =
print_endline "Doing something."
let cleanup () =
print_endline "Cleaning up before moving on."
let () =
Utils.try_finalize do_thing () cleanup ()
Fill in the Makefile:
bin=bin
build=build
docs=docs
exe=myutility.byte
all: clean build doc
build:
rm -rf $(bin)
rm -rf $(build)
mkdir $(bin)
mkdir $(build)
cp src/* $(build)/
ocamlc -c -I $(build) $(build)/utils.mli
ocamlc -c -I $(build) $(build)/utils.ml
ocamlc -c -I $(build) $(build)/main.ml
ocamlc -o $(bin)/$(exe) unix.cma build/utils.cmo build/main.cmo
doc:
rm -rf $(docs)
mkdir $(docs)
ocamldoc -d $(docs) -html -I $(build) $(build)/*.ml*
clean:
rm -rf $(build) $(bin) $(docs)/* **/*.cm* $(exe) **/*~ **/*.swp
Now build:
make
Run the executable:
./bin/myutility.byte
Check the documentation, for instance:
lynx docs/Utils.html