This extension provides a syntax for string interpolation. Here is an example of its features:
let script_remotely (user : string) (host : string) (port : int) (script : string) =
[%string "ssh %{user}@%{host} -p %{port#Int} %{Sys.quote script}"]
The above expression is equivalent to:
let script_remotely (user : string) (host : string) (port : int) (script : string) =
String.concat ""
[ "ssh "
; user
; "@"
; host
; " -p "
; Int.to_string port
; " "
; Sys.quote script
]
Compared to Printf.sprintf
:
let script_remotely (user : string) (host : string) (port : int) (script : string) =
sprintf "ssh %s@%s -p %d %s" user host port (Sys.quote script)
having the values inline instead of after the format string can make it easier to understand the resulting string, and avoids the potential mistake of passing arguments in the wrong order. This is truer the more format arguments there are. On the other hand, some things are much easier with printf: pad numbers with zeroes, pad strings on the right, display floats in a specific formats, etc.
Compared to manually writing something like String.concat
version above,
ppx_string is shorter and can oftentimes be less error-prone (it’s really easy
to forget whitespace after ssh
or around -p
in the explicit String.concat
version).
To emit the literal sequence %{
, you can escape it as follows:
[%string {|%{"%{"}|}]
To pad strings with spaces on the left, add an integer expression after a colon:
[%string "%{col1#Int:term_width / 2}%{col2#:term_width/4}%{col3#:8}%{col4}"]
is equivalent to:
let pad str len =
let pad_len = max 0 (String.length str - len) in
let padding = String.make pad_len ' ' in
padding ^ str
in
String.concat ""
[ pad (Int.to_string col1) (term_width / 2)
; pad col2 (term_width / 4)
; pad col3 8
; col4
]
(note that the pad length can be dynamic, as with the format string “%*s”)