diff --git a/NEWS.md b/NEWS.md index 744b4c70f691a..3509e3dd93445 100644 --- a/NEWS.md +++ b/NEWS.md @@ -161,8 +161,12 @@ Deprecated or removed * `scale` is deprecated in favor of either `α*A`, `Diagonal(x)*A`, or `A*Diagonal(x)`. ([#15258]) + * `xdump` is removed, and `dump` now simply shows the full representation of a value. + `dump` should not be overloaded, since it is for examining concrete structure ([#4163]). + [PkgDev]: https://github.com/JuliaLang/PkgDev.jl +[#4163]: https://github.com/JuliaLang/julia/issues/4163 [#4211]: https://github.com/JuliaLang/julia/issues/4211 [#8036]: https://github.com/JuliaLang/julia/issues/8036 [#8846]: https://github.com/JuliaLang/julia/issues/8846 diff --git a/base/deprecated.jl b/base/deprecated.jl index 1bee11aa391af..8cc2004a4ec5e 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -985,7 +985,6 @@ export call # 1933 @deprecate_binding SingleAsyncWork AsyncCondition - # #12872 @deprecate istext istextmime @@ -1073,6 +1072,9 @@ end @deprecate bitunpack(B::BitArray) Array(B) @deprecate bitpack(A::AbstractArray) BitArray(A) +# #4163 +@deprecate xdump dump + # During the 0.5 development cycle, do not add any deprecations below this line # To be deprecated in 0.6 diff --git a/base/docs/helpdb/Base.jl b/base/docs/helpdb/Base.jl index b941f5969884c..c07d9edf61152 100644 --- a/base/docs/helpdb/Base.jl +++ b/base/docs/helpdb/Base.jl @@ -1692,7 +1692,7 @@ split """ dump(x) -Show all user-visible structure of a value. +Show every part of the representation of a value. """ dump @@ -8867,13 +8867,6 @@ true """ applicable -""" - xdump(x) - -Show all structure of a value, including all fields of objects. -""" -xdump - """ Base.process_messages(instrm::AsyncStream, outstrm::AsyncStream) diff --git a/base/exports.jl b/base/exports.jl index 70d3cac5f8083..fb98b94349c2a 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -899,7 +899,6 @@ export utf32, warn, wstring, - xdump, # random numbers AbstractRNG, diff --git a/base/show.jl b/base/show.jl index e24f5720191f8..1ad6c6abfc951 100644 --- a/base/show.jl +++ b/base/show.jl @@ -933,99 +933,115 @@ function show(io::IO, tv::TypeVar) end end -# dump & xdump - structured tree representation like R's str() -# - dump is for the user-facing structure -# - xdump is for the internal structure -# -# x is the object -# n is the depth of traversal in nested types (5 is the default) -# indent is a character string of spaces that is incremented at -# each descent. -# -# Package writers may overload dump for other nested types like lists -# or DataFrames. If overloaded, check the nesting level (n), and if -# n > 0, dump each component. Limit to the first 10 entries. When -# dumping components, decrement n, and add two spaces to indent. -# -# Package writers should not overload xdump. +function dump(io::IO, x::SimpleVector, n::Int, indent) + if isempty(x) + print(io, "empty SimpleVector") + return + end + print(io, "SimpleVector") + if n > 0 + for i = 1:length(x) + println(io) + print(io, indent, " ", i, ": ") + if isassigned(x,i) + dump(io, x[i], n - 1, string(indent, " ")) + else + print(io, undef_ref_str) + end + end + end +end -function xdump(fn::Function, io::IO, x, n::Int, indent) +function dump(io::IO, x::ANY, n::Int, indent) T = typeof(x) - print(io, T, " ") - if isa(T, DataType) && nfields(T) > 0 - println(io) + if isa(x, Function) + print(io, x, " (function of type ", T, ")") + else + print(io, T) + end + if nfields(T) > 0 if n > 0 - for field in fieldnames(T) - if field != symbol("") # prevents segfault if symbol is blank - print(io, indent, " ", field, ": ") - if isdefined(x,field) - fn(io, getfield(x, field), n - 1, string(indent, " ")) - else - println(io, undef_ref_str) - end + for field in (isa(x,Tuple) ? (1:length(x)) : fieldnames(T)) + println(io) + print(io, indent, " ", field, ": ") + if isdefined(x,field) + dump(io, getfield(x, field), n - 1, string(indent, " ")) + else + print(io, undef_ref_str) end end end else - println(io, x) + !isa(x,Function) && print(io, " ", x) end + nothing end -function xdump(fn::Function, io::IO, x::Module, n::Int, indent) - print(io, Module, " ") - println(io, x) -end -function xdump_elts(fn::Function, io::IO, x::Array{Any}, n::Int, indent, i0, i1) + +dump(io::IO, x::Module, n::Int, indent) = print(io, "Module ", x) + +function dump_elts(io::IO, x::Array, n::Int, indent, i0, i1) for i in i0:i1 print(io, indent, " ", i, ": ") if !isdefined(x,i) - println(io, undef_ref_str) + print(io, undef_ref_str) else - fn(io, x[i], n - 1, string(indent, " ")) + dump(io, x[i], n - 1, string(indent, " ")) end + i < i1 && println(io) end end -function xdump(fn::Function, io::IO, x::Array{Any}, n::Int, indent) - println(io, "Array($(eltype(x)),$(size(x)))") - if n > 0 - xdump_elts(fn, io, x, n, indent, 1, (length(x) <= 10 ? length(x) : 5)) - if length(x) > 10 - println(io, indent, " ...") - xdump_elts(fn, io, x, n, indent, length(x)-4, length(x)) + +function dump(io::IO, x::Array, n::Int, indent) + print(io, "Array($(eltype(x)),$(size(x)))") + if eltype(x) <: Number + print(io, " ") + show(io, x) + else + if n > 0 && !isempty(x) + println(io) + if limit_output(io) + dump_elts(io, x, n, indent, 1, (length(x) <= 10 ? length(x) : 5)) + if length(x) > 10 + println(io) + println(io, indent, " ...") + dump_elts(io, x, n, indent, length(x)-4, length(x)) + end + else + dump_elts(io, x, n, indent, 1, length(x)) + end end end end -xdump(fn::Function, io::IO, x::Symbol, n::Int, indent) = println(io, typeof(x), " ", x) -xdump(fn::Function, io::IO, x::Function, n::Int, indent) = println(io, x) -xdump(fn::Function, io::IO, x::Array, n::Int, indent) = - (print(io, "Array($(eltype(x)),$(size(x))) "); - show(io, x); println(io)) +dump(io::IO, x::Symbol, n::Int, indent) = print(io, typeof(x), " ", x) # Types -xdump(fn::Function, io::IO, x::Union, n::Int, indent) = println(io, x) -function xdump(fn::Function, io::IO, x::DataType, n::Int, indent) - println(io, x, "::", typeof(x), " ", " <: ", supertype(x)) - fields = fieldnames(x) - if n > 0 - for idx in 1:min(10, length(fields)) - if fields[idx] != symbol("") # prevents segfault if symbol is blank +dump(io::IO, x::Union, n::Int, indent) = print(io, x) + +function dump(io::IO, x::DataType, n::Int, indent) + print(io, x) + if x !== Any + print(io, " <: ", supertype(x)) + end + if !(x <: Tuple) + fields = fieldnames(x) + if n > 0 + for idx in 1:length(fields) + println(io) print(io, indent, " ", fields[idx], "::") - if isa(x.types[idx], DataType) - xdump(fn, io, fieldtype(x,idx), n - 1, string(indent, " ")) - else - println(io, fieldtype(x,idx)) - end + #if isa(x.types[idx], DataType) + # xdump(fn, io, fieldtype(x,idx), n - 1, string(indent, " ")) + #else + print(io, fieldtype(x,idx)) + #end end end - if length(fields) > 10 - println(io, indent, " ...") - end end end # dumptype is for displaying abstract type hierarchies like Jameson # Nash's wiki page: https://github.com/JuliaLang/julia/wiki/Types-Hierarchy -function dumptype(io::IO, x, n::Int, indent) +function dumptype(io::IO, x::ANY, n::Int, indent) # based on Jameson Nash's examples/typetree.jl println(io, x) if n == 0 # too deeply nested @@ -1066,50 +1082,12 @@ end # For abstract types, use _dumptype only if it's a form that will be called # interactively. -xdump(fn::Function, io::IO, x::DataType) = x.abstract ? dumptype(io, x, 5, "") : xdump(fn, io, x, 5, "") -xdump(fn::Function, io::IO, x::DataType, n::Int) = x.abstract ? dumptype(io, x, n, "") : xdump(fn, io, x, n, "") - -# defaults: -xdump(fn::Function, io::IO, x) = xdump(xdump, io, x, 5, "") # default is 5 levels -xdump(fn::Function, io::IO, x, n::Int) = xdump(xdump, io, x, n, "") -xdump(fn::Function, io::IO, args...) = throw(ArgumentError("invalid arguments to xdump")) -xdump(fn::Function, args...) = xdump(fn, STDOUT::IO, args...) -xdump(io::IO, args...) = xdump(xdump, io, args...) -xdump(args...) = xdump(xdump, IOContext(STDOUT::IO, :limit_output => true), args...) -xdump(arg::IO) = xdump(xdump, STDOUT::IO, arg) - -# Here are methods specifically for dump: -dump(io::IO, x, n::Int) = dump(io, x, n, "") -dump(io::IO, x) = dump(io, x, 5, "") # default is 5 levels -dump(io::IO, x::AbstractString, n::Int, indent) = - (print(io, typeof(x), " "); - show(io, x); println(io)) -dump(io::IO, x, n::Int, indent) = xdump(dump, io, x, n, indent) -dump(io::IO, args...) = throw(ArgumentError("invalid arguments to dump")) -dump(arg::IO) = xdump(dump, STDOUT::IO, arg) -dump(args...) = dump(IOContext(STDOUT::IO, :limit_output => true), args...) - -function dump(io::IO, x::Dict, n::Int, indent) - println(io, typeof(x), " len ", length(x)) - if n > 0 - i = 1 - for (k,v) in x - print(io, indent, " ", k, ": ") - dump(io, v, n - 1, string(indent, " ")) - if i > 10 - println(io, indent, " ...") - break - end - i += 1 - end - end -end +dflt_io() = IOContext(STDOUT::IO, :limit_output => true) +dump(io::IO, x::DataType; maxdepth=8) = (x.abstract ? dumptype : dump)(io, x, maxdepth, "") +dump(x::DataType; maxdepth=8) = (x.abstract ? dumptype : dump)(dflt_io(), x, maxdepth, "") -# More generic representation for common types: -dump(io::IO, x::DataType, n::Int, indent) = println(io, x.name) -dump(io::IO, x::DataType, n::Int) = dump(io, x, n, "") -dump(io::IO, x::DataType) = dump(io, x, 5, "") -dump(io::IO, x::TypeVar, n::Int, indent) = println(io, x.name) +dump(io::IO, arg; maxdepth=8) = dump(io, arg, maxdepth, "") +dump(arg; maxdepth=8) = dump(dflt_io(), arg, maxdepth, "") """ diff --git a/test/show.jl b/test/show.jl index 56d29e132b98c..0175099923833 100644 --- a/test/show.jl +++ b/test/show.jl @@ -279,7 +279,6 @@ oldout = STDOUT try rd, wr = redirect_stdout() @test dump(STDERR) == nothing - @test xdump(STDERR) == nothing finally redirect_stdout(oldout) end