Dynamicly change the Base.show methods with using macro?

There is two methods showing Float64:

t1show(io,x::Float64)=begin
    if x<1e-3
        xshow=x/1e-4 |> x->round(2,digits=2)
        print(io,string(xshow)*" bp")
    else
        print(io,string(x))
    end
end

t2show(io,x::Float64)=print(io,string(x))

Sometimes I want using t1show to show Float64, I would run this code:

Base.show(io::IO,x::Float64)=t1show(io,x)

0.0004
"4 bp"

Othertimes, I would like to show Float64 with using t2show, then I have to run this code:

Base.show(io::IO,x::Float64)=t2show(io,x)
0.0004
0.0004

This is not convinient. So does there is a elegant way to get like this:

0.0004
0.0004

@somemacro t2show 0.0004
"4 bp"

0.0004
0.0004

Finally, I find a way to do it:

macro cshow(f,expr)
    func=eval(f)
    ft=methods(func)[1].sig.parameters[3]
    return quote
        Base.show(io::IO,a::$ft)=$func(io,a)
        x=$expr
        show(x)
        Base.delete_method(methods(Base.show,(IO,$ft))[1])
    end |>esc
end

@cshow t1show 0.0004
4 bp

0.0004
0.0004

Why not just call t1show(0.0004) when that’s what you want? What’s the advantage of the macro?

I use it in jupyter, when call t1show, it needs the parameter “io”.

You need to define t1show(x) = t1show(stdout, x)

I tried just now, This method has a problem, I have to define functions : tshow(x::Float64) tshow(x::Vector)...., this is not convnient.

You can define a fallback: tshow(x::Any) = show(x).

1 Like