See the discussion in the following issue, which discusses your case and potential solutions:
https://github.com/JuliaLang/julia/issues/4209 Cheers, Kevin On Mon, Feb 3, 2014 at 8:06 AM, Alexander Samoilov < [email protected]> wrote: > Thanks a lot for the hint and for the useful code hack. > > Let me elaborate a bit about multiple @printf in order to avoid > misunderstanding and explain the use case: > > I was translating from Fortran > > ```Fortran > write(50,1001) mptr,level,mx > > 1001 format(i5,' grid_number',/, > & i5,' AMR_level',/, > & i5,' mx') > ``` > The 1st variant of translation with a big format string: > > ```julia > @printf(unit50, > "%5d grid_number\n%5d > AMR_level\n%5d mx\n", > mptr,level,mx) > ``` > > i.e. is not very pretty-looking as the format string is too big. > > In C it can be written as > > ```C > printf(unit50, > "%5d grid_number\n" > "%5d AMR_level\n" > "%5d mx\n", > mptr,level,mx); > ``` > due to consecutive tokens pasting. > > Finally I gave up and just wrote: > > ```julia > @printf(unit50,"%5d grid_number\n",mptr) > @printf(unit50,"%5d AMR_level\n",level) > @printf(unit50,"%5d mx\n",mx) > ``` > > Thanks, > Alexander > > On Monday, February 3, 2014 7:39:04 AM UTC+4, Jake Bolewski wrote: >> >> I don't think you can do this as a macro, you want to use a function >> instead wrapping multiple @printf's as you stated. >> >> the behavior you are asking for is to partially evaluate the string >> function at compile time (hack) >> >> macro myprintf(args...) >> if length(args) == 0 >> error("@myprintf: called with zero arguments") >> end >> if isa(args[1], String) || (isa(args[1], IO) && isa(args[1], String)) >> :(@printf($(args...))) >> else >> local io, func, fargs >> if isa(args[1], Expr) >> io = :(Base.STDOUT) >> func = args[1].args[1] >> fargs = args[1].args[2:end] >> elseif (isa(args[1], IO) && isa(args[2], Expr)) >> io = args[1].args[1] >> func = args[1].args[2] >> fargs = args[1].args[3:end] >> else >> error("better message here") >> end >> for i in 1:length(fargs) >> if isa(fargs[i], Symbol) >> fargs[i] = getfield(current_module(), fargs[i]) >> end >> end >> fmt_string = apply(getfield(Base, func), fargs...) >> :(@printf($io, $fmt_string, $(args[2:end]...))) >> end >> end >> >> however this does not work at all with local scope. >> >> julia> a = "This is " >> "This is " >> >> julia> b = "a test: %d" >> "a test: %d" >> >> julia> @myprintf(string(a, b), 10) >> This is a test: 10 >> julia> let a = "test1 ", b = "test2 %d" >> @myprintf(string(a, b), 10) >> end >> This is a test: 10 >> julia> >> >> >> Best, >> Jake >> >> On Sunday, February 2, 2014 6:53:04 PM UTC-5, John Myles White wrote: >>> >>> Hi Alexander, >>> >>> I’m not aware of a way to do this, but would also like to know how to do >>> it. >>> >>> — John >>> >>> On Feb 2, 2014, at 5:52 AM, Alexander Samoilov < >>> [email protected]> wrote: >>> >>> > Hello, >>> > >>> > I have a format string - a "%Fmt" literal for @printf() and it is too >>> large, so would like to concatenate it from chunks, >>> > say using string("chunk 1 ", " chunk 2 ", " chunk 3 ") >>> > >>> > @printf() disallow to do it as requires a string literal, but string() >>> is a function and the produced string variable cannot be checked vs. >>> @printf() args. >>> > >>> > julia> @printf(string("abc ", " def ", " ggg ")) >>> > ERROR: first or second argument must be a format string >>> > >>> > Looks this is intentionally to have an opportunity to check format >>> string vs. parameters (at least check number of args). >>> > >>> > BTW, C allows gluing of a few consecutive strings, e.g. "abc " " def >>> " " ggg " into one string literal, though it doesn't look very aesthetic. >>> > >>> > Is it possible for Julia to construct a format string somehow and feed >>> it to @printf() or this is impossible in principle >>> > and several invocations of @printf() should be used as workaround? >>> > >>> > Thanks, >>> > Alexander >>> >>>
