show() and display() for arrays

1,027 views
Skip to first unread message

David van Leeuwen

unread,
Nov 27, 2013, 5:43:47 PM11/27/13
to julia...@googlegroups.com
Hello, 

for my NamedArray I am trying to implement pretty-printing.  I can't find the code that is pretty printing Arrays in the REPL---so I've based my stuff on how DataFrame does this. 

I am confused about the name of the methods called from the REPL---I thought this was 

show(io::IO, x::NamedArray)



Now, in the special case where my NamedArray <: AbstractArray is actually a NamedVector (i.e., the dimension is 1) the REPL shows a bunch of #undef's, and it seems that instead I need to overload

display(d::TextDisplay, x::NamedVector)


in order to pretty-print a NameArray{T,1} properly.  This seems to be inconsistent (a call of show() vs display()). 

Am I missing something here?

---david

Steven G. Johnson

unread,
Nov 27, 2013, 7:22:31 PM11/27/13
to julia...@googlegroups.com
You only need to overload show().  The display(x) function calls writemime(io, "text/plain", x), which calls showlimited(io, x), which calls show(io, x).

The issue here is probably that there is a method ambiguity.

* Base defines show(io, x::AbstractVector) [which calls show_vector] and show(io, x::AbstractArray) [which calls showarray], both in base/show.jl

* You defined show(io, x::NamedArray).  This is more specific than show(io, x::AbstractArray) because NamedArray is a specific subtype of AbstractArray), it should definitely get called for displaying NamedArray instances with ndims > 1

* However, it is ambiguous whether show(io, x::NamedArray) is more specific than show(io, x::AbstractVector).  AbstractVector is equivalent to AbstractArray{T,1}.  The type is more abstract than NamedArray in that it is a more abstract base type, but on the other hand the type is more specific than yours because it specifies a particular dimensionality.

Julia resolves this by calling show(io, x::AbstractVector) if show() is called with a NamedArray of dimension 1.

The solution is to simply define

show(io::IO, x::NamedVector) = invoke(show, (IO, NamedArray), io, x)

so that you have a show which is unambiguously more specific than show(io, x::AbstractVector) for 1d NamedArrays.

David van Leeuwen

unread,
Nov 28, 2013, 3:52:18 AM11/28/13
to julia...@googlegroups.com
Hello Steven, 
This seems to make sense, although it is a rather complicated business, but it doesn't work for me (I defined a show(io::IO, x::NamedVector) as you suggested)

julia> NamedArray(rand(3))
3-element NamedArray{Float64,1}:
 #undef
 #undef
 #undef

julia> show(NamedArray(rand(3)))
3-element NamedArray{Float64,1}
1 0.499392
2 0.271866
3 0.188658

so in my version of the REPL (I compiled a stock v0.2.0 on MacOS) there is a difference between show() and the function that the REPL calls to show something, and specifically for a 1-d NamedArray. I really need to define an explicit 

display(d::TextDisplay, v::NamedVector) = show(d.io, v)

but perhaps I should overload show_vector() instead?

---david
Reply all
Reply to author
Forward
0 new messages