Unixのようなシステムを使っているなら、Unix.dup2を使ってほぼすべての種類の入力リダイレクトを行うことができます。ここには、入力ファイル名、関数、および値をとる関数with_stdin
があります。指定されたファイルからリダイレクトされた標準入力で関数を呼び出します。
let with_stdin fname f x =
let oldstdin = Unix.dup Unix.stdin in
let newstdin = Unix.openfile fname [Unix.O_RDONLY] 0 in
Unix.dup2 newstdin Unix.stdin;
Unix.close newstdin;
let res = f x in
Unix.dup2 oldstdin Unix.stdin;
Unix.close oldstdin;
res
関数が入力全体を消費しない場合、残りの入力はトップレベルを混乱させます。ここではその全体の入力を消費しない例を示します。
# let rec linecount c =
try ignore (read_line()); linecount (c + 1)
with End_of_file -> c;;
val linecount : int -> int = <fun>
# with_stdin "/etc/passwd" linecount 0;;
- : int = 86
#
この技術は、あなたがその入力の一部だけを消費するようにあなたの関数への呼び出しでトップレベルとの相互作用をインターリーブしたい場合は、あまりにも簡単です。私はそれが努力する価値があることが複雑すぎると思う。明示的に指定された入力チャンネルで動作するようにコードを書き直すほうがはるかに簡単です(おそらく全体的には良いでしょう)。
関連性があります:http://stackoverflow.com/questions/22257343/ocaml-input-redirection –
@AntonTrunovジェフリーは、自分自身を繰り返しているように見えます.-D – Lhooq