"show" nested struct

How can I use the show method for a type that is nested in another struct? For example:

julia> struct A
           x::Int
       end

julia> Base.show(io::IO, ::MIME"text/plain", a::A) = print(io, ">>A$(a.x)")

julia> struct B
           x::A
       end

julia> a = A(1)
>>A1       # what I expected in displaying A

julia> function Base.show(io::IO, ::MIME"text/plain", b::B) 
           println(io, "B containing:")
           print(b.x) # how can I use the show(::A) method here?
       end

julia> b = B(a)
B containing:
A(1)               # not what I expect when displaying A

Ok, I found it, just had pass io and mime around:

julia> function Base.show(io::IO, mime::MIME"text/plain", b::B) 
           println(io, "B containing:")
           show(io, mime, b.x) 
       end

julia> b = B(a)
B containing:
>>A1

If that is not the correct way to do it, let me know :slight_smile:

Now, how to properly indent the nested shows? I found this: Nested indentation in show

But it seems that those keywords do not work anymore.

This does call show(io, A), but note that print calls the two-argument show function. You typically define the 3-argument show in addition to the 2-argument show, if you want a more verbose multi-line pretty-printing in addition to compact output (for use in e.g. REPL output via display), as explained in the manual on Custom pretty printing.

I’m not sure what you mean — you can still add indentation metadata to IOContext in the same way:

Base.show(io::IO, ::MIME"text/plain", a::A) = print(io, ' '^get(io, :indent, 0), ">>A$(a.x)")
function Base.show(io::IO, mime::MIME"text/plain", b::B)
    indent = get(io, :indent, 0)
    println(io, ' '^indent, "B containing:")
    show(IOContext(io, :indent => indent+4), mime, b.x)
end

which gives

julia> B(A(1))
B containing:
    >>A1
3 Likes

Thanks, I was not getting the syntax right from the example in the other post, and the help entry of IOContext does not mention indentation, so I was lost.