MWE (tested on Julia 1.11.5):
julia> struct MyT{T}
a::T
end
julia> import Base: show
julia> Base.show(io::IO, ::MIME, obj::MyT) = print(io, typeof(obj), "(...)")
julia> MyT(1)
Error showing value of type MyT{Int64}:
SYSTEM (REPL): showing an error caused an error
ERROR: MethodError: no method matching display(::MyT{Int64})
Based on the documentation, this worked:
julia> struct MyT{T} # In a new Julia REPL process
a::T
end
julia> import Base: show
julia> Base.show(io::IO, ::MIME"text/plain", obj::MyT) = print(io, typeof(obj), "(...)")
julia> MyT(1)
MyT{Int64}(...)
Does this mean one should always specify the MIME type they want to customize “show” for?
Thanks!!
Yes. It makes no sense to have a MIME-independent show
method.
For example, why would you use the same method for text/plain
and img/png
?
Note, however, that error here is misleading and should probably be fixed. The real reason display
is throwing an error is that the method dispatch is ambiguous. We can see the true error if we call a lower-level method:
julia> display(Base.Multimedia.displays[1], MyT(1))
ERROR: MethodError: show(::Base.TTY, ::MIME{Symbol("text/plain")}, ::MyT{Int64}) is ambiguous.
Candidates:
show(io::IO, ::MIME{Symbol("text/plain")}, x)
@ Base.Multimedia multimedia.jl:47
show(io::IO, ::MIME, obj::MyT)
@ Main REPL[3]:1
Possible fix, define
show(::IO, ::MIME{Symbol("text/plain")}, ::MyT)
Stacktrace:
[1] display(d::TextDisplay, M::MIME{Symbol("text/plain")}, x::Any)
@ Base.Multimedia ./multimedia.jl:254
[2] display(d::TextDisplay, x::Any)
@ Base.Multimedia ./multimedia.jl:255
[3] top-level scope
@ REPL[15]:1
The Base.show
method is ambiguous because there is a MIME"text/plain"
fallback method for any type of x
, as well as your show
method for any MIME
but a specific type of x
.
4 Likes
Thanks for the explanation!