Browse thread
[Caml-list] Printf and format
-
Sylvain LE GALL
-
Pierre Weis
-
Sylvain LE GALL
- Xavier Leroy
-
Sylvain LE GALL
-
Pierre Weis
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Xavier Leroy <xavier.leroy@i...> |
| Subject: | Re: [Caml-list] Printf and format |
> Is there a way to transform string to ( 'a, out_channel, unit, unit)
> format. I need this function to use it with something like :
>
> Printf.printf (my_fun "X, Y") "coucou";;
No, not in a type-safe manner. The type of a format string depends on
the "%" specifiers found in the string itself, and OCaml can't infer
or check types at run-time.
However, for the purpose of internationalization, the following
operation suffices: given a (compile-time constant) format and a
(dynamically computed) string, check that the string can be viewed as
a format with the same format type as the constant format, and return
the string as a format.
In OCaml 3.06, this can be done as follows:
let re_fmt =
Str.regexp "%[#0-9.*+ -]*[lnL]?[sScCdioxXunfeEgGFbBatn[]"
let string_of_format (s : ('a, 'b, 'c) format) = (Obj.magic s : string)
let extract_formats s =
List.fold_right
(fun part accu ->
match part with Str.Text _ -> accu | Str.Delim d -> d :: accu)
(Str.full_split re_fmt s) []
let conv_format (src: ('a, 'b, 'c) format) (dst: string) =
if extract_formats (string_of_format src) = extract_formats dst
then (Obj.magic dst : ('a, 'b, 'c) format)
else failwith "conv_format"
Remark 1: yes, there's a lot of "Obj.magic" in this code, and yes,
this is a deadly sin, but in this particular instance it is all
type-safe nonetheless.
Remark 2: the matching of the two formats can be relaxed, e.g.
the code above will not allow the conversion of "%6d" into "%8x",
although both formats have the same type. This is left as an exercise
for the reader. But for internationalization purposes, I doubt
you need that additional flexibility.
Then, assuming you have a function "gettext : string -> string" to translate
strings according to the user-selected language, you can extend it to
formats as follows:
let getformat f = conv_format f (gettext (string_of_format f))
and use it with printf functions like this:
printf (getformat "My name is %s and I'm %d years old") "Bob" 12
> you read my mind. Indeed, the question concern an internationalization
> module ( let's call libgettext-ocaml ). It is basically a binding of
> gettext.
I hope the above is enough to get you off the ground.
- Xavier Leroy
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners