Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In OCaml, how can I create an out_channel which writes to a string/buffer instead of a file on disk

Tags:

io

ocaml

I have a function of type in_channel -> out_channel -> unit which will output something to an out_channel. Now I'd like to get its output as a string. Creating temporary files to write and read it back seems ugly, so how can I do that? Is there any other methods to create out_channel besides Pervasives.open_out family?

Actually, this function implemented a repl. What I really need is to test it programmatically, so I'd like to first wrap it to a function of type string -> string. For creating the in_channel, it seems I can use Scanf.Scanning.from_string, but I don't know how to create the out_channel parameter.

like image 413
Tianyi Cui Avatar asked Sep 22 '12 03:09

Tianyi Cui


2 Answers

OCaml Batteries Included has output_string and output_buffer functions in its BatIO module which seem to do what you want: http://ocaml-batteries-team.github.com/batteries-included/hdoc/BatIO.html

It might require you to use their input/output types.

like image 145
newacct Avatar answered Nov 11 '22 23:11

newacct


If you don't mind your tests relying on the Unix module, then you can use Unix.pipe to create a file descriptor pair, create an in_channel from the readable side, an out_channel from the writable side, and then write the string to the writable side and pass the in_channel to the code under test.

val pipe : unit -> file_descr * file_descr

Create a pipe. The first component of the result is opened for reading, that's the exit to the pipe. The second component is opened for writing, that's the entrance to the pipe.

val in_channel_of_descr : file_descr -> Pervasives.in_channel

Create an input channel reading from the given descriptor. The channel is initially in binary mode; use set_binary_mode_in ic false if text mode is desired.

val out_channel_of_descr : file_descr -> Pervasives.out_channel

Create an output channel writing on the given descriptor. The channel is initially in binary mode; use set_binary_mode_out oc false if text mode is desired.

Unix pipes are a bit heavy-weight for anything with high throughput, but they should be fine for a test-harness.

like image 4
Mike Samuel Avatar answered Nov 11 '22 23:11

Mike Samuel