Defining custom show method on REPL for custom Array

I’m trying to define a custom show method for my TestArray below:

struct TestA{T} <: AbstractVector{T}
   a::Vector{T}
   b::Vector{Complex{T}}
   isita::Base.RefValue{Bool}
end

TestA() = TestA{Float64}(rand(Float64,3),rand(ComplexF64,3),Ref(true))

Base.getindex(a::TestA,I) = a.a[I]
Base.size(a::TestA) = size(a.a)

For interactive usage, I want it to, based on the value of isita, to show either the field a or b.
That is, this behavior:

julia> a = TestA();

julia> a.isita[] = true
true

julia> a
3-element Array{Float64,1}:
 0.14678500223886437
 0.08462746912533947
 0.8586140490403353

julia> a.isita[] = false
false

julia> a
3-element Array{Complex{Float64},1}:
 0.07338388695512643 + 0.2851322043342337im
  0.1638922033011161 + 0.5194807635340914im
  0.4607592481784579 + 0.16060301189885262im

In order for that to happen, I tried defining the following:

Base.show(io::IO,::MIME"text/plain",a::TestA) = a.isita[] ? show(io,MIME"text/plain",a.a) : show(io,MIME"text/plain",a.b)

But that leads to this odd error message:

julia> a
Error showing value of type TestA{Float64}:
ERROR: MethodError: no method matching display(::TestA{Float64})
Closest candidates are:
  display(::Any) at multimedia.jl:284
  display(::AbstractDisplay, ::AbstractString, ::Any) at multimedia.jl:178
  display(::AbstractString, ::Any) at multimedia.jl:179
  ...
Stacktrace:
 [1] display(::TestA{Float64}) at ./multimedia.jl:294
 [2] #invokelatest#1 at ./essentials.jl:686 [inlined]
 [3] invokelatest at ./essentials.jl:685 [inlined]
 [4] print_response(::IO, ::Any, ::Any, ::Bool, ::Bool, ::Any) at /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:154
 [5] print_response(::REPL.AbstractREPL, ::Any, ::Any, ::Bool, ::Bool) at /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:139
 [6] (::getfield(REPL, Symbol("#do_respond#40")){Bool,getfield(REPL, Symbol("##50#59")){REPL.LineEditREPL,REPL.REPLHistoryProvider},REPL.LineEditREPL,REPL.LineEdit.Prompt})(::Any, ::Any, ::Any) at /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:708
 [7] #invokelatest#1 at ./essentials.jl:686 [inlined]
 [8] invokelatest at ./essentials.jl:685 [inlined]
 [9] run_interface(::REPL.Terminals.TextTerminal, ::REPL.LineEdit.ModalInterface, ::REPL.LineEdit.MIState) at /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/REPL/src/LineEdit.jl:2261
 [10] run_frontend(::REPL.LineEditREPL, ::REPL.REPLBackendRef) at /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:1029
 [11] run_repl(::REPL.AbstractREPL, ::Any) at /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:191
 [12] (::getfield(Base, Symbol("##720#722")){Bool,Bool,Bool,Bool})(::Module) at ./logging.jl:311
 [13] #invokelatest#1 at ./essentials.jl:686 [inlined]
 [14] invokelatest at ./essentials.jl:685 [inlined]
 [15] macro expansion at ./logging.jl:308 [inlined]
 [16] run_main_repl(::Bool, ::Bool, ::Bool, ::Bool, ::Bool) at ./client.jl:330
 [17] exec_options(::Base.JLOptions) at ./client.jl:242
 [18] _start() at ./client.jl:421

Can someone point me the right direction to get this working?

1 Like

You forgot the parens after the mime type. It should be

Base.show(io::IO,::MIME"text/plain",a::TestA) = a.isita[] ? show(io,MIME"text/plain"(),a.a) : show(io,MIME"text/plain"(),a.b)

or, more succinctly,

Base.show(io::IO,m::MIME"text/plain",a::TestA) = a.isita[] ? show(io,m,a.a) : show(io,m,a.b)
2 Likes

I was so close! :smile: