Repository: JuliaLang/julia
File: base/show.jl (Julia)

Code before:
function array_summary(io::IO, a, inds)
    print(io, dims2string(length.(inds)), " ")
    showarg(io, a, true)
    print(io, " with indices ", inds2string(inds))
end

## `summary` for Function
summary(io::IO, f::Function) = show(io, MIME"text/plain"(), f)

"""
    Base.showarg(io::IO, x, toplevel)

Show the quasi-type of `x` where quasi-type is the type of `x` or an expression (possibly
containing quasi-types) that would generate an object of the same type as `x`. The shorter
of these two options is typically used.

This function is used by summary to display type information in terms of sequences of
function calls on objects.

Show a leading `::` if `toplevel` is `false` and showing a type. `toplevel` is `true` if
this is the direct call from `summary` and `false` for nested (recursive) calls.

The fallback definition is to print x as "::$(typeof(x))", representing argument x in terms
of its type. (The double-colon is omitted if toplevel=true.) However, you can specialize
this function for specific types to customize printing. This customization is useful for
types that have simple constructors and verbose types such as `reinterpret`ed arrays or
`SubArray`s.

# Examples

A SubArray created as `view(a, :, 3, 2:5)`, where `a` is a
3-dimensional Float64 array, has type

    SubArray{Float64, 2, Array{Float64, 3}, Tuple{Colon, Int64, UnitRange{Int64}}, false}

The default `show` printing would display this full type.
However, the summary for SubArrays actually prints as

    2×4 view(::Array{Float64, 3}, :, 3, 2:5) with eltype Float64

because of a definition similar to

    function Base.showarg(io::IO, v::SubArray, toplevel)
        print(io, "view(")
        showarg(io, parent(v), false)
        print(io, ", ", join(v.indices, ", "))
        print(io, ')')
        toplevel && print(io, " with eltype ", eltype(v))
    end

Note that we're calling `showarg` recursively for the parent array

Review comment (suggestion):
Might be worth mentioning that this is also useful if the API for the constructor is public but the specifics of the underlying type are not intended to be public facing.

Code after:

# printing iterators from Base.Iterators

function show(io::IO, e::Iterators.Enumerate)
    print(io, "enumerate(")
    show(io, e.itr)
    print(io, ')')
end
show(io::IO, z::Iterators.Zip) = show_delim_array(io, z.is, "zip(", ',', ')', false)

# pretty printing for Iterators.Pairs
function Base.showarg(io::IO, r::Iterators.Pairs{<:Integer, <:Any, <:Any, T}, toplevel) where T<:AbstractArray
    print(io, "pairs(IndexLinear(), ::", T, ")")
end

function Base.showarg(io::IO, r::Iterators.Pairs{Symbol, <:Any, Nothing, T}, toplevel) where {T <: NamedTuple}
    print(io, "pairs(::NamedTuple)")
end

function Base.showarg(io::IO, r::Iterators.Pairs{<:Any, <:Any, I, D}, toplevel) where {D, I}
    print(io, "Iterators.Pairs(::", D, ", ::", I, ")")
end

# printing BitArrays

# (following functions not exported - mainly intended for debug)

function print_bit_chunk(io::IO, c::UInt64, l::Integer = 64)
    for s = 0:l-1
        d = (c >>> s) & 1
        print(io, "01"[d + 1])
        if (s + 1) & 7 == 0
            print(io, " ")
        end
    end
end

print_bit_chunk(c::UInt64, l::Integer) = print_bit_chunk(stdout, c, l)
print_bit_chunk(c::UInt64) = print_bit_chunk(stdout, c)

function bitshow(io::IO, B::BitArray)
    isempty(B) && return
    Bc = B.chunks
    for i = 1:length(Bc)-1
        print_bit_chunk(io, Bc[i])
        print(io, ": ")
    end
    l = _mod64(length(B)-1) + 1
    print_bit_chunk(io, Bc[end], l)
end
bitshow(B::BitArray) = bitshow(stdout, B)