Show an object in extended form vs short form

my problem is the following:
I have a type with fields, and i want those fields to be displayed with additional detail when shown alone in the REPL:

julia> a = MyType(;params....)
MyType properties, with:
a: ....
b: .....

Also, i want this type to be displayed shortly when inside of a container:

julia> a = MyType(;params....);b = MyType(;params2....);(a,b) #tuple, it can be a vector
(MyType(a=1,b=2...),MyType(a2=2,b2=2))

i know that arrays implement this type of contex-aware show, as:

julia> a = rand(2)
2-element Array{Float64,1}:
 0.3972476935276372
 0.25401198033393935

julia> (a,a)
([0.3972476935276372, 0.25401198033393935], [0.3972476935276372, 0.25401198033393935])

any ideas on how to implement this, What functions do i have to overload to change the behaviour?

1 Like

Short answer is you over-ride Base.show with a behavior for regular and compact contexts

i have this code to test the behaviour, but the IO doesnt pass a compact = true when inside arrays or tuples:

struct MyType
    a
end

function Base.show(io::IO, x::MyType)
    compact = get(io,:compact,false)
    a = x.a
    if compact
        println("My type with one element:")
        println("a (",typeof(a),"):",a)
    else
        print("MyType(",a,")")
    end
end

a = MyType(2)
b = (a,a)

to add more information:

julia> show(rand(2))
[0.24607512874238346, 0.7404663542415493]
julia> display(rand(2))
2-element Array{Float64,1}:
 0.3096292761559558
 0.7676667676433597

i know that the show method ultimately dispatches to display

Rather than with compact, the way to do this is to overload two methods of show. One with signature show(::IO, ::MyObject), which will apply for “compact printing” and another with signature show(::IO, ::MIME"text/plain", ::MyObject) which will apply to “display” printing like top level repl.

3 Likes

yes! this is what i’m looking for: a proof of concept:

struct MyType
    a
end
function Base.show(io::IO, x::MyType)
    a = x.a    
    print(io,"MyType(",a,")")
    end

function Base.show(::IO, ::MIME"text/plain", x::MyType)
    a = x.a
    println(io,"My type with one element:")
    println(io,"a (",typeof(a),"):",a)
end

in the REPL:

julia> a = MyType(2)
My type with one element:
a (Int64):2


julia> (a,a)
(MyType(2), MyType(2))
3 Likes