Append to file (instead of overwrite) with Jane St Core

Hello, everyone, I recently encountered a problem, has been bothering me, I would like to ask you, thank you!
First, look at the following code,This code defines a function that receives the output file path in the form of a string and the string that needs to be output.

open Core.Std
let create_number_file filename str =
	let outc =Out_channel.create filename in
	protect ~f:(fun ()->fprintf outc "str = %s\n" str)
	~finally:(fun() ->Out_channel.close outc)

But this function clears the log file every time. I want to add data to the log file in an append way. When I create log files, if I have the log file, I will add the data to the end of the file. How do I do this?

Out_channel.create takes an optional boolean argument append. With your example, that would mean:

open Core.Std
let create_number_file filename str =
	let outc =Out_channel.create ~append:true filename in
	protect ~f:(fun ()->fprintf outc "str = %s\n" str)
	~finally:(fun() ->Out_channel.close outc)
1 Like

Thank you, it works.I don’t know where I can see the API of these functions. I looked at OCaml’s website, but I didn’t find an API document like java.

OCaml ecosystem does not have a centralized place hosting docs as of now. But you can google “OCaml project-name doc”, since most popular projects offer online doc. It works for core.

There are a few ways to figure out the signature for an api without going online. You can install Merlin on your text editor and read the info below autocompletion. You can also use utop. To check the signature of a particular function, run function_name;;, and to checkout the signature for the whole module, you can use #show ModuleName;;.

1 Like

Fantastic! I’ve been using utop to get some modules and functions’ signatures, but it’s not detailed. I’ll try your method. Thank you very much!

In addition to what @gersonmoraes said above, another way to get documentation about a package that’s installed on your system is odig:

% opam install odoc odig
...
% odig doc $(some_package)

The above should open your browser with a generated documentation extracted from the package itself, featuring all public values and their types, alongside the corresponding doc strings.
Very valuable tool in my opinion.

2 Likes

Yeah, I think it would be a great tool, too. Thank you.

Google doesn’t like Core’s documentation for some reason (always wants to send people to ancient versions). I just keep this bookmarked:

https://ocaml.janestreet.com/ocaml-core/latest/doc/

(Or for previous versions: https://ocaml.janestreet.com/ocaml-core/ – although the docs improved substantially in v0.10 so you might want to use that version of the docs even if you’re using an older version of the library)

The closest thing to a full-fledged OCaml API doc site is http://docs.mirage.io/

Unfortunately, it’s not very searchable. For example, if you go to the above page looking for the Core.Std.Out_channel.create function, you’ll be shown a list of OPAM package names and you’ll have to know that core is the package that contains this function.

Anyway, once you go into core looking for the function, you can, with a little luck, navigate through a series of indirect modules and eventually come to http://docs.mirage.io/stdio/Stdio/Out_channel/index.html#val-create

There you can see that the type of the function is defined slightly above the function itself, http://docs.mirage.io/stdio/Stdio/Out_channel/index.html#type-with_create_args . You might wonder why they did that.

Interestingly, if you search for that type, with_create_args, you’ll see the function with_file, which seems to take a file handler function and creation arguments, and lets you perform some operation. I’m not sure because it’s not documented, but from the type of the function, it might actually be opening the file, doing an operation on it, and automatically closing it–in other words, doing the same job as protect + create!

You can try it out:

open Core.Std

let create_number_file filename str = Out_channel.with_file
  ~append:true
  filename
  ~f:(fun outc -> fprintf outc "str = %s\n" str)

And if it works for you and you’re feeling helpful, you could send a PR documenting this function so the next person can get it a little quicker :slight_smile:

1 Like

Thank you for your suggestion. The problem has been solved.