- Docker + Ubuntu 18.04 での環境の用意
- とりあえず cat コマンドを書いてみた
たぶん3日坊主になると思うので、 ホスト側の環境を汚さないように Docker で環境を用意する。 ホストも Ubuntu です。
この記事を参考に。何も分からないので助かります。
WSL の Ubuntu 18.04 で OCaml 開発環境を作る - Qiita
FROM ubuntu:18.04 RUN apt update \ && apt install -y --no-install-recommends \ ca-certificates \ curl \ m4 \ nano \ ocaml \ opam \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* ARG USER ARG GROUP RUN groupadd ${USER} \ && useradd ${USER} -g ${GROUP} -m USER ${USER} RUN mkdir /home/${USER}/work WORKDIR /home/${USER}/work
コーディングはホスト側で行うので Emacs は省く。
イメージをビルド
docker build \ --build-arg USER=$USER \ --build-arg GROUP=$(id -gn) \ -t ocaml-env:test .
コンテナを起動
docker run -it \ -v ${PWD}:/home/${USER}/work \ --name ocaml-env-container \ ocaml-env:test
コンテナ内で残りの作業。 コーディングはホスト側で行うので tuareg などは省いて utop だけインストール。
opam init -y eval `opam config env` echo "" >> ~/.bashrc echo 'eval `opam config env`' >> ~/.bashrc opam install -y utop
(yes | opam install ...
だとうまくいかなくて仕方なく対話的にやっていたけど、
-y
オプションを見つけて解決した。
ので、これらの opam まわりの作業も Dockerfile に入れてしまえるはず。)
exit で抜けたりした後またコンテナ内に入りたいときは
# コンテナが止まっていたら start で再開して # docker start ocaml-env-container docker exec -it ocaml-env-container bash
ホスト側でコードを書く。
https://github.com/ocaml/tuareg
から tuareg.el
だけ取ってきてカレントディレクトリに置いて、
Emacs で
(progn (load (concat (file-name-as-directory default-directory) "tuareg.el")) (tuareg-mode))
を評価すると、構文ハイライトされて M-;
でコメントアウト・コメントインできるようになる。
賢い補完とかはできないけど、そこらへんは3日坊主にならなかったら整えるということで。
(2020-02-27 追記: tuareg-opam.el
も必要)
(2020-12-29 追記)
tuareg-opam.el
もカレントディレクトリに置いた上で、カレントディレクトリを load-path に追加して下記のようにしました。
tuareg.el
内で tuareg-opam
を require しているようです。
(progn (add-to-list 'load-path default-directory) (load "tuareg.el") (tuareg-mode))
cat コマンド書く。
参考: お気楽 OCaml プログラミング入門 (8) ファイル入出力 | M.Hiroi's Home Page
参考にして書いてたつもりが、いじってたら結局 M.Hiroi さんのコード例のまんまになってしまいました。
(* cat.ml *) let () = let rec cat_line () = print_string (read_line ()); print_newline (); cat_line () in try cat_line () with End_of_file -> ();;
コンテナ内で実行。
ls | ocaml cat.ml
2021-06-10 追記
1バイトずつ読み書きするバージョンの cat:
let () = let rec cat_byte_sub () = output_byte stdout (input_byte stdin); cat_byte_sub () in try cat_byte_sub () with End_of_file -> ()
さらに \n
を <LF>\n
に変換するようにしたもの:
let () = let print_byte (byte : int) = match byte with | 10 -> print_string "<LF>\n" | _ -> output_byte stdout byte in let rec cat_byte_sub () = print_byte (input_byte stdin); cat_byte_sub () in try cat_byte_sub () with End_of_file -> ()
2021-06-17 追記
https://hub.docker.com/r/ocaml/ocaml
試していませんが Docker Hub にそれっぽいイメージがありました。 official image の表記がない点に注意。
関連
このときは(サードパーティのライブラリを使わないため)opam は不要で、ocamlc/ocamlopt コマンドだけ使えればいいやということになり、ocaml パッケージのみインストールして使いました。 リポジトリに Dockerfile があるのでそれを見ていただければと。