struct Box
size::Int
matrix::Matrix{ComplexF64}
end
and my aim is to implement a custom show method for a Box that will display its matrix in a nice rectangle form (not printing all the elements in a row). I would expect that I have to write smth like this:
function Base.show(io::IO, box::Box)
println(io, "Box of size $(box.size):"
println(io, " matrix:")
print(io, box.matrix)
end
but it prints all the matrix elements in one row. Using display(box.matrix) inside show(io::IO, box::Box) prints the matrix in a nice rectangle form, but it does it two times for some reason…
Your code with display works fine for me (though it’s probably not ideal we don’t use io there, you could use Base.show(io, "text/plain", box.matrix) instead):
struct Box
size::Int
matrix::Matrix{ComplexF64}
end
function show(io::IO, box::Box)
println(io, "Box of size $(box.size):")
println(io, " matrix:")
display(box.matrix)
end
box = Box(3, rand(ComplexF64, 3, 3))
Oh, right. Calling show(stdout, box) indeed prints it only once. And after printing just box in the Julia REPL prints it only once. However, in VScode editing window, when I press Shift+Enter to evaluate the command box, it prints it twice in the REPL for some reason:
(and Shift + Enter on show(stdout, box) works as intended, with a single pretty print).
Perhaps you have installed other relevant extensions apart from the official Julia extension, or changed some settings of the latter, altering VS Code’s behaviour when displaying variables?
If you Shift+Enter on a line box;, do you still get a double print?
I have only one Julia extension installed in VScode.
If I Shift+Enter on a line box; I get nothing printed. If I Shift+Enter on box gives me double pretty print, and Shift+Enter on println(box) gives single pretty print…
But what if you extend the show function from the Base module using function Base.show(io::IO, box::Box)?
Oh yeah, that would make more sense. (I see you added the Base. in an edit, presumably after I started typing my first reply, so I always worked with the original (implicit) Main. version.)
With the Base.show version I do get the nice prints (using box, show(stdout, box) or println(box)), but still only one (both for scripts and Jupyter notebooks).
It seems that this problem arises due to not specifying the IO in the display method. (I am using Apple M1 machine, if it is important…) Suppose I have the following code:
struct Box
size::Int
matrix::Matrix{ComplexF64}
end
function Base.show(io::IO, box::Box)
println(io, "Box of size $(box.size):")
println("111")
println(io, " matrix:")
println("222")
display(box.matrix)
end
box = Box(3, rand(ComplexF64, 2, 2))
In particular, the show method you are defining should probably be the 3-argument show, not the 2-argument show:
function Base.show(io::IO, mime::MIME"text/plain", box::Box)
...
end
and then call show(io, mime, box.matrix). The reason is that you are defining a multi-line verbose representation designed for human consumption, whereas the 2-argument show should normally be a single-line and compatible with how you enter the Box in Julia (this is the default).