Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiline shebang in OCaml?

In short, I'd like to abstract this shebang so I can literally copy and paste it into other .ML files without having to specify the filename each time:

#!/usr/bin/env ocamlscript -o hello

print_endline "Hello World!"

I realize I could just drop the -o hello bit, but I'd like all the binaries to have UNIX names (hello), instead of Windows names (hello.ml.exe).

You need a complex shebang to do this. A Clojure example that has the desired behavior:

":";exec clj -m `basename $0 .clj` $0 ${1+"$@"}
":";exit

Clojure is Java-based, which is why clj needs the basename of the file (something, not something.clj). In order to get the basename, you need a multiline shebang, because a single line shebang can only handle a single, simple, static command line argument. In order to do multiline shebangs, you need a syntax which simultaneously:

  • Sends shell commands to the shell
  • Hides the shell commands from the main language

Does anyone know of OCaml trickery to do this? I've tried the following with no success:

(*
exec ocamlscript -o `basename $0 .ml` $0 ${1+"$@"}
exit
*)

let rec main = print_endline "Hello World!"
like image 434
mcandre Avatar asked Oct 19 '25 09:10

mcandre


1 Answers

What you're looking for is a shell and Objective Caml polyglot (where the shell part invokes an ocaml interpreter to perform the real work). Here's a relatively simple one. Adapt to use ocamlscript if necessary, though I don't see the point.

#!/bin/sh
"true" = let exec _ _ _ = "-*-ocaml-*- vim:set syntax=ocaml: " in
exec "ocaml" "$0" "$@"
;;
(* OCaml code proper starts here *)
print_endline "hello"
like image 171
Gilles 'SO- stop being evil' Avatar answered Oct 22 '25 05:10

Gilles 'SO- stop being evil'



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!