Extending `@show` from Base

Viewed 108

How do I extend Base's @show macro to my own types?

Example:

struct friendly
    string
end

Base.show(f::friendly) = f.string * " :)"

p = friendly("people")

And then calling show(p) returns:

"people :)"

But @show p just does the normal thing (notebook result):

p = friendly("people")

friendly("people")

I tried extending the macro from base:

Base.@show(f::friendly) = f.string * " :)"

But that errors with:

syntax: invalid assignment location "begin
    Base.println("f::friendly = ", Base.repr(begin
    # show.jl, line 576
    #105#value = f::friendly
end))
    #105#value
end"

Stacktrace:
 [1] top-level scope at C:\Users\User\.julia\packages\IJulia\cwvsj\src\kernel.jl:52
1 Answers

@show does something very simple: prints the expression, then =, then the value of the expression. If you want some other behavior you should probably define your own macro. If what you want is to control how the value is printed on the right hand side you should extend Base.show. When extending Base.show it is very important that the first argument is an I/O buffer (e.g. io::IO), and that your method writes to that I/O buffer. That is what's missing from your example. This works:

julia> struct Friendly
           x::String
       end

julia> Base.show(io::IO, f::Friendly) = print(io, f.x, " :)")

julia> f = Friendly("Hi")
Hi :)

julia> @show f;
f = Hi :)

Notice that the updated Base.show method now also results in "pretty printing" when the value is printed in the Julia REPL:

julia> f = Friendly("Hi")
Hi :)
Related