gulpでファイルを監視してocamlのインタプリタで走らせる

おつかれさまです無職です。仕事はまだ決まっていません。暇にまかせてDDD本マラソン(エヴァンス本->ヴァヴァ本->エヴァンス本)しましたけど、ヴァヴァ本先に読んでたらエヴァンス本2周しなくてよかったのではという感じです。

というわけで有職期に手をつけられなかったのをどんどんやってます。次は「プログラミングの基礎」です。どうでもいい近況でした。

さて

とにかくmlファイル編集の度に勝手に走ってほしい!

ocamlをインタプリタで実行すると、関数の返り値などの型情報が詳細に返ってきてこれって学習のために結構重要な要素が気がする!ですが、ocamlコマンドにファイルを直接渡すと、ただただ結果が返ってきます。

というか(おれが)それしか方法を知りません。

expectという対話型インターフェースと戦うコマンドがある

apt get install expect

なりなんなりすると一瞬で使えるようになる一般的な有名コマンドで、sshに対する自動ログインから処理までを書いたりして最高!というやつです。

これを使えばインタプリタともよろしくやれてほんと最高。

インタプリタでやる処理をシェルスクリプトで用意する

#!/bin/sh

FILE=$1

expect -c "
spawn ocaml
expect \"#\"
send \"#use \\\"$FILE\\\";;\n\"
expect \"#\"
expect \"#\"
send \"#quit;;\n\"
interact
"

\\\"$FILE\\\"ここらへんがかわいいですね。

ファイルパスを引数に渡して実行するgulpfileを用意する

var gulp = require("gulp");
var watch = require("gulp-watch");
var changed = require('gulp-changed');
var shell = require('gulp-shell');
var plumber = require('gulp-plumber');

var srcs = '../ocaml/*.ml';

gulp.task('default', function() {
  gulp.watch(srcs).on('change', function(event) {
    gulp.src(event.path)
      .pipe(plumber({
        errorHandler: function(err) {
          console.log(err);
          this.emit('end');
        }
      })).pipe(shell([
        '../ex.sh <%= file.path %>',
        'echo '
      ], {}));
  });
});

実行

spawn ocaml
        OCaml version 4.01.0

# #use "/home/ten/ocaml/kyuyo.ml";;
val jikyu : int = 950
val yugu_jikyu : int = 980
val kihonkyu : int = 100
val use_jikyu : int -> int = <fun>
val kyuyo : int -> int = <fun>
val test1 : bool = true
val test2 : bool = true
val test3 : bool = true
# #quit;;
spawn ocaml
        OCaml version 4.01.0

# #use "/home/ten/ocaml/tsurukame.ml";;
val tsurukame : int -> int -> int = <fun>
val test1 : bool = true
val test2 : bool = true
val test3 : bool = true
val test4 : bool = true
val test5 : bool = true
# #quit;;

やった!

おれがんばるよ。

ああ

勉強は楽しいんだけど、貯蓄が尽きるまでに再就職できるんだろうか。