Многострочный шебанг в OCaml? - PullRequest
       26

Многострочный шебанг в OCaml?

2 голосов
/ 30 сентября 2011

Короче говоря, я хотел бы абстрагировать этот shebang, чтобы я мог буквально копировать и вставлять его в другие файлы .ML без необходимости каждый раз указывать имя файла:

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

print_endline "Hello World!"

Я понимаю, что могу простоудалите бит -o hello, но я бы хотел, чтобы все двоичные файлы имели имена UNIX (hello) вместо имен Windows (hello.ml.exe).

Для этого нужен сложный шебанг.Пример Clojure с требуемым поведением:

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

Clojure основан на Java, поэтому clj необходимо базовое имя файла (something, а не something.clj).Чтобы получить базовое имя, вам нужен многострочный шебанг, потому что однострочный шебанг может обрабатывать только один простой статический аргумент командной строки.Для выполнения многострочных шебангов необходим синтаксис, который одновременно:

  • Отправляет команды оболочки в оболочку
  • Скрывает команды оболочки от основного языка

Кто-нибудь знает об обмане OCaml, чтобы сделать это?Я пробовал следующее безуспешно:

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

let rec main = print_endline "Hello World!"

Ответы [ 3 ]

5 голосов
/ 30 сентября 2011

То, что вы ищете - это оболочка и полиглот Objective Caml (где часть оболочки вызывает интерпретатор ocaml для выполнения реальной работы).Вот относительно простой.При необходимости используйте ocamlscript, хотя я не вижу смысла.

#!/bin/sh
"true" = let exec _ _ _ = "-*-ocaml-*- vim:set syntax=ocaml: " in
exec "ocaml" "$0" "$@"
;;
(* OCaml code proper starts here *)
print_endline "hello"
2 голосов
/ 27 февраля 2015

После некоторых испытаний я нашел этот шебанг:

#!/bin/sh
"true" = let x' = "" in (*'
    sh script here
*) x'

Это своего рода улучшение предложения Жиля, поскольку оно позволяет написать полный сценарий оболочки внутри комментария OCaml, не беспокоясь овсе с несовместимостью синтаксиса.

Сценарий должен завершиться (например, с exec или exit) без достижения конца комментария, в противном случае произойдет синтаксическая ошибка.Это можно легко исправить, но это не очень полезно для предполагаемого использования такого трюка.

Вот вариант, который влечет за собой нулевые издержки времени выполнения на стороне OCaml, но объявляет новое имя типа (выберите егопроизвольно усложняется, если это беспокоит):

#!/bin/sh
type int' (*' >&- 2>&-
    sh script here
*)

Например, вот скрипт, который выполняет код OCaml с модулями Str и Unix, а также может компилировать его при передаче параметра --compile:

#!/bin/sh
type int' (*' >&- 2>&-
    if [ "$1" = "--compile" ]; then
        name="${0%.ml}"
        ocamlopt -pp 'sed "1s/^#\!.*//"' \
          str.cmxa unix.cmxa "$name.ml" -o "$name" \
          || exit
        rm "$name".{cm*,o}
        exit
    else
        exec ocaml str.cma unix.cma "$0" "$@"
    fi
*)
0 голосов
/ 30 сентября 2011

Я не думаю, что ocamlscript поддерживает это. Возможно, стоит отправить запрос функции автору, чтобы разрешить настройку расширения скомпилированного двоичного файла без указания полного выходного базового имени.

...