# Custom show for a struct that contains matrix

**URL:** https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816
**Category:** New to Julia
**Tags:** show
**Created:** [September 24, 2024, 4:23pm UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816 "2024-09-24T16:23:24Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![azoviktor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/azoviktor/32/206405_2.png) [@azoviktor](https://discourse.julialang.org/u/azoviktor)
#### Post date: [September 24, 2024, 4:23pm UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816/1 "2024-09-24T16:23:24Z")

</div>

Suppose I have a struct

```julia
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:

```julia
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…

---

<div class="post-metadata">

### Author: ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)
#### Post date: [September 24, 2024, 4:32pm UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816/2 "2024-09-24T16:32:21Z")

</div>

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):

```julia
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))

```

```julia-repl
julia> show(stdout, box)
Box of size 3:
 matrix:
3×3 Matrix{ComplexF64}:
 0.110489+0.490646im 0.216738+0.506696im 0.806984+0.535515im
 0.569361+0.497763im 0.990934+0.791805im 0.344692+0.786712im
 0.662557+0.48268im 0.550246+0.0305454im 0.0693276+0.143775im

```

I don’t know why would you get something different, but perhaps you’re somehow accidentally returning `box.matrix` from `show`?

```julia-repl
julia> function show(io::IO, box::Box)
          println(io, "Box of size $(box.size):")
          println(io, " matrix:")
          display(box.matrix); box.matrix
       end
show (generic function with 1 method)

julia> show(stdout, box)
Box of size 3:
 matrix:
3×3 Matrix{ComplexF64}:
 0.110489+0.490646im 0.216738+0.506696im 0.806984+0.535515im
 0.569361+0.497763im 0.990934+0.791805im 0.344692+0.786712im
 0.662557+0.48268im 0.550246+0.0305454im 0.0693276+0.143775im
3×3 Matrix{ComplexF64}:
 0.110489+0.490646im 0.216738+0.506696im 0.806984+0.535515im
 0.569361+0.497763im 0.990934+0.791805im 0.344692+0.786712im
 0.662557+0.48268im 0.550246+0.0305454im 0.0693276+0.143775im

julia> show(stdout, box);
Box of size 3:
 matrix:
3×3 Matrix{ComplexF64}:
 0.110489+0.490646im 0.216738+0.506696im 0.806984+0.535515im
 0.569361+0.497763im 0.990934+0.791805im 0.344692+0.786712im
 0.662557+0.48268im 0.550246+0.0305454im 0.0693276+0.143775im

```

---

<div class="post-metadata">

### Author: ![azoviktor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/azoviktor/32/206405_2.png) [@azoviktor](https://discourse.julialang.org/u/azoviktor)
#### Post date: [September 24, 2024, 4:40pm UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816/3 "2024-09-24T16:40:01Z")

</div>

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:

```julia
Box of size 3:
 matrix:
3×3 Matrix{ComplexF64}:
  0.207312+0.832938im 0.656108+0.173641im 0.661501+0.384587im
  0.983555+0.684514im 0.292562+0.617771im 0.0917733+0.096517im
 0.0218214+0.730983im 0.986447+0.37221im 0.095009+0.715964im

3×3 Matrix{ComplexF64}:
  0.207312+0.832938im 0.656108+0.173641im 0.661501+0.384587im
  0.983555+0.684514im 0.292562+0.617771im 0.0917733+0.096517im
 0.0218214+0.730983im 0.986447+0.37221im 0.095009+0.715964im

```

But maybe it is the problem with VScode…

---

<div class="post-metadata">

### Author: ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)
#### Post date: [September 24, 2024, 4:50pm UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816/4 "2024-09-24T16:50:47Z")

</div>

In my VS Code Shift + Enter on a line containing only the `box` variable prints the same as `println(box)`:

```julia-repl
Box(3, ComplexF64[0.17059151873830936 + 0.6467902853991271im 0.5516890187413159 + 0.16840124279428315im 0.04774010114262217 + 0.03149348949086228im; 0.16131392705103242 + 0.03850134950744866im 0.42382508938133245 + 0.2807228527058967im 0.32199193022264194 + 0.06329937630082594im; 0.6228329149783915 + 0.3768341650812741im 0.7527126699625651 + 0.16822047117462158im 0.36431680664443533 + 0.469961437362322im])

```

(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?

---

<div class="post-metadata">

### Author: ![azoviktor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/azoviktor/32/206405_2.png) [@azoviktor](https://discourse.julialang.org/u/azoviktor)
#### Post date: [September 24, 2024, 5:00pm UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816/5 "2024-09-24T17:00:51Z")

</div>

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)`?

---

<div class="post-metadata">

### Author: ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)
#### Post date: [September 24, 2024, 5:09pm UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816/6 "2024-09-24T17:09:07Z")

</div>

> [@azoviktor](#):
>
> 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).

---

<div class="post-metadata">

### Author: ![azoviktor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/azoviktor/32/206405_2.png) [@azoviktor](https://discourse.julialang.org/u/azoviktor)
#### Post date: [September 24, 2024, 6:23pm UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816/7 "2024-09-24T18:23:00Z")

</div>

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:

```julia
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))

```

Then the Shift+Enter command applied to `box` gives

```julia
Box of size 3:
111
 matrix:
222
2×2 Matrix{ComplexF64}:
 0.305076+0.347138im 0.456306+0.974372im
 0.169632+0.881314im 0.435036+0.345573im

111
222
2×2 Matrix{ComplexF64}:
 0.305076+0.347138im 0.456306+0.974372im
 0.169632+0.881314im 0.435036+0.345573im

```

Would you know maybe another way than `display` to pretty print a matrix which takes IO as an argument?

---

<div class="post-metadata">

### Author: ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)
#### Post date: [September 24, 2024, 6:25pm UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816/8 "2024-09-24T18:25:23Z")

</div>

Well, you could try `Base.show(io, "text/plain", box.matrix)`.

---

<div class="post-metadata">

### Author: ![azoviktor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/azoviktor/32/206405_2.png) [@azoviktor](https://discourse.julialang.org/u/azoviktor)
#### Post date: [September 24, 2024, 6:30pm UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816/9 "2024-09-24T18:30:46Z")

</div>

Ooh, awesome, it works well now. I should probably read about MIMEs in the Julia docs and what they are used for… Thank you!!

You actually suggested this in your first answer, but I overlooked it ☹

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [September 24, 2024, 6:55pm UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816/10 "2024-09-24T18:55:47Z")

</div>

> [@azoviktor](#):
>
> Ooh, awesome, it works well now. I should probably read about MIMEs in the Julia docs and what they are used for… Thank you!!

In particular, the `show` method you are defining should probably be the 3-argument `show`, not the 2-argument `show`:

```julia
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).

This is all described in the manual’s [chapter on custom pretty-printing](https://docs.julialang.org/en/v1/manual/types/#man-custom-pretty-printing). You might also want to check out the [new summary of output functions](https://github.com/JuliaLang/julia/blob/2943833bea8a8c05f47de1edc154bbb6888547a1/doc/src/manual/types.md#output-function-summary) that will appear in the next version of the manual.

---

<div class="post-metadata">

### Author: ![azoviktor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/azoviktor/32/206405_2.png) [@azoviktor](https://discourse.julialang.org/u/azoviktor)
#### Post date: [September 25, 2024, 9:51am UTC](https://discourse.julialang.org/t/custom-show-for-a-struct-that-contains-matrix/119816/11 "2024-09-25T09:51:23Z")

</div>

Thank you!
