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
>>>
>>>

Reply via email to