4
votes

I'm trying to create a specialized pretty-print function for a Julia struct that will output in the desired way to a Jupyter nb. My specialized show obviously works if I just blat one of the structs as the result of the nb frame, but not if I call show in code:

using Printf
struct foo
    bar
end
show(io::IO, ::MIME"text/plain", f::foo) = @printf(io, "A Foo with Bar=%s!!!",f.bar)
f1=foo(1234)
show(f1)                     # A
f1                           # B

Output (with # comments added):

foo(1234)                    # This comes from the inline show (A)
A Foo with Bar=1234!!!       # This is the result that's just blatted out from the eval (B)

I've tried many version of this -- importing and over-riding Base.show, using print and println instead of show, and importing/overriding those, and so on and so forth. Many versions work like above. Some break in various predictable ways, but no combination that I've tried lets me output into the nb stream through my specialized fn (i.e., I want #A to look like #B). I'm sure it's simple, but I'm obviously just missing something

2

2 Answers

1
votes

There are two issues in the code you posted:

  1. in order to extend the show function from Base, you should be explicit about it: either import Base: show or explicitly define your method for Base.show
  2. while (as a developer) show is the good function to extend for new types, you (as a user) should still use display to display values.

Fixing these yields:

using Printf
struct foo
    bar
end

# Explicitly extend Base.show to tell how foo should be displayed
Base.show(io::IO, ::MIME"text/plain", f::foo) = @printf(io, "A Foo with Bar=%s!!!",f.bar)

f1=foo(1234)

# Call display to actually display a foo
display(f1)   # -> A Foo with Bar=1234!!! (printed on stdout)
f1            # -> A Foo with Bar=1234!!! (displayed as output)
0
votes

While the question has been answered by @François Févotte please note that it is worth to use the Parameters package to obtain nice struct printing. It might suit your need or not but is worth to know.

Use this short code as a guidance.

julia> using Parameters

julia> struct S1            
       x::Int               
       b::String            
       end                  
                            
julia> @with_kw struct S2   
       x::Int               
       b::String            
       end                  
S2                          
                            
julia> S1(5, "Hello")       
S1(5, "Hello")              
                            
julia> S2(5, "Hello")       
S2                          
  x: Int64 5                
  b: String "Hello"