Escaping in nested expr

I’m trying to write a simple macro to enable/disable color output within a block (for running tests that capture and compare output)

This is what I have so far, but I can’t figure out the right escaping for prev_color at the end to restore the original color. I need it to refer to the prev_color defined inside the quote block.

macro color_output(enabled, block)
    quote
        prev_color = Base.have_color
        eval(Base, :(have_color = $$enabled))
        $(esc(block))
        eval(Base, :(have_color = $prev_color))
    end
end

Seems like a bug to me. In the mean time, you can always use Expr(:(=), :have_color, prev_color).

Alternatively, you can esc() everything and handle the hygiene issue yourself:

macro color_output(enabled, block)
    p = gensym()
    esc(quote
        $p = Base.have_color
        eval(Base, :(have_color = $$enabled))
        $block
        eval(Base, :(have_color = $$p))
    end)
end
1 Like

Thanks for the ideas. It’s nice that I wasn’t just being dense. :slight_smile:

It appears this is issue #17558.