I am building a parallel unit test runner using MailBoxProcessor.
I need to queue up print statements for a test, so I can print them once a test is finished. I know how to send a string and build up a list so I can print them, but that forces me to use sprintf
and pipe it into my print function and is not as clean as I would like.
[1..200]
|> List.iter (fun i ->
sprintf "Test %i" i &&& fun ctx ->
ctx.printfn <| sprintf "A guid %A" (ng())
ctx.printfn <| sprintf "I am test %i" i
ctx.printfn <| sprintf "A guid %A" (ng()))
You can see the full code here: https://github.com/lefthandedgoat/prunner/blob/master/Program.fs#L36-L41
And see that ctx
is an object with a printfn
method that takes a string and posts it to a single mailbox that queues up messages until a tests is done, then loops over them and prints them.
My goal is to have the ctx.printfn
look like this
[1..200]
|> List.iter (fun i ->
sprintf "Test %i" i &&& fun ctx ->
ctx.printfn "A guid %A" (ng())
ctx.printfn "I am test %i" i
ctx.printfn "A guid %A" (ng()))
The TextWriterFormat is the key component that “knows” the type of the format string, such as string->unit or string->int->unit, which in turn allows printf to be typesafe.
The reasons are: It is statically type checked. It is a well-behaved F# function and so supports partial application, etc. It supports native F# types. Unlike String.Format, printf is statically type checked, both for the types of the parameters, and the number.
The function printf () does two things: it generates a formatted string based on the arguments passed into it, and it outputs the string to stdout. This article demonstrates how to define what stdout means in your application, enabling you to use printf () when you need to.
There are cases where it is perfectly valid to pass a UNICODE character pointer to a printf style function. valid and then give a warning if one of those arguments don't match. I certainly don't expect that of the compiler. They would have to update functions. printf allows a %S (note capital S). If it encounters one, then it's
Your question isn't entirely clear, but you may be able to achieve your goal via kprintf:
member x.printfn fmtStr =
Printf.kprintf (fun msg -> reporter.Post(Print(msg, x.TestId))) fmtStr
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With