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] <javascript:>> 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