Weird Base.show behavior with custom Struct

For some reason checking my custom Struct in the REPL differs from the Base.show() method I defined. Can anyone replicate and/or explain why this might be happening?

Here is a MWE to (hopefully) replicate the behavior:

using Graphs
import Base: show

mutable struct myNewGraph{N, T<:Integer} <: Graphs.AbstractSimpleGraph{T}
    ne::N                         #Number of edges
    fadjlist::Vector{Vector{T}}   #Sorted adjacency list [src]: (dst, dst, dst)
end

function show(io::IO, space::myNewGraph)
    println(io, "My new type with $(space.ne) edge")
end

Graphs.is_directed(::Type{<:myNewGraph}) = false
Graphs.is_directed(g::myNewGraph) = false

space = myNewGraph(1, [[1]])

And here is what happens when I display the struct instance in the REPL:

julia> space
{1, 1} undirected simple Int64 graph

julia> show(space)
My new type with 1 edge

julia> Base.show(space)
My new type with 1 edge

Yeah, this is a bit confusing, the explanation for it is buried in here: Types · The Julia Language

Basically, when you display a top level form in the REPL, what get’s called is not show(stdout, x) but instead show(stdout, MIME"text/plain"(), x). So the easiest fix for you would be to write something like

Base.show(io::IO, space::myNewGraph) = println(io, "My new type with $(space.ne) edge")
Base.show(io::IO, ::MIME"text/plain", space::myNewGraph) = show(io, space)
1 Like

I’ll definitely have to read this part of the manual more carefully. Do you know if this is a recent change in the Base.show() behavior? I was revising some code from a few months ago when I stumbled upon this. (also thank you, I was banging my head against the wall trying to figure this out)

It’s been this way since before Julia 1.0

However, realize that the 3-argument show(io, mimetype, x) calls the 2-argument show(io, x) by default, so when you define a new type you normally only need to define the latter if you want the two cases to look the same.

The problem here is that, 6 months ago, Graphs.jl decided to override show(io, ::MIME"text/plain", x) instead of show(io, x) (Graphs.jl#121), so whenever you define a subtype of Graphs.AbstractSimpleGraph you need to override both show methods if you want customized behavior in both the REPL and in print etcetera.

1 Like