MeasureBase.jl icon indicating copy to clipboard operation
MeasureBase.jl copied to clipboard

Printing StackOverflowError

Open keorn opened this issue 3 years ago • 7 comments

If one implements custom AbstractMeasure and not override any printing methods this method leads to an error: https://github.com/cscherrer/MeasureBase.jl/blob/master/src/utils.jl#L3

That is most likely because pprint falls back to show at some point.

Replicate in REPL:

julia> using MeasureBase: AbstractMeasure
julia> struct A <: AbstractMeasure end
julia> A()
Error showing value of type A:
ERROR: StackOverflowError:

Few ways to address it, not sure which one you prefer.

keorn avatar Dec 03 '21 16:12 keorn

Thanks @keorn . I didn't realize this was a problem in master, but I did hit this a couple of times in the refactoring I'm doing in dev. I added this, which I think gives a reasonable fallback:

function Pretty.tile(d::AbstractMeasure)
    M = Symbol(constructor(d))
    the_names = fieldnames(typeof(d))
    isempty(the_names) && return Pretty.literal(M)*Pretty.literal("()")
    Pretty.list_layout(Pretty.tile.([getfield(d, n) for n in the_names]); prefix=M)
end

Then we can override that for particular types whenever it makes sense.

cscherrer avatar Dec 03 '21 16:12 cscherrer

I would prefer if by default AbstractMeasure would print in the default Base way. Just because something is an AbstractMeasure should not affect its string representation.

keorn avatar Dec 03 '21 20:12 keorn

Hmm good point, that is a little strange. I mean, it's usually what I want, but kind of arbitrary to impose on new types an end-user might build.

cscherrer avatar Dec 03 '21 21:12 cscherrer

https://github.com/MechanicalRabbit/PrettyPrinting.jl/issues/5

cscherrer avatar Dec 04 '21 00:12 cscherrer

I've updated this so the default mimics Base as closely as possible:

function Pretty.tile(d::M) where {M<:AbstractMeasure}
    the_names = fieldnames(typeof(d))
    result = Pretty.literal(repr(M))
    isempty(the_names) && return result * Pretty.literal("()")
    Pretty.list_layout(Pretty.tile.([getfield(d, n) for n in the_names]); prefix=result)
end

I'll close this for now, but I'm open to alternatives if the PrettyPrinting issue leads to a better approach or if you have a PR. Please reopen in that case.

cscherrer avatar Dec 05 '21 15:12 cscherrer

Great, thanks. This temporary solution makes sense.

keorn avatar Dec 05 '21 16:12 keorn

Reopening, since @xitology gave some helpful information in response to MechanicalRabbit/PrettyPrinting.jl#5. We don't need to finalize this right away, but my quick fix shouldn't be considered the final solution.

cscherrer avatar Dec 06 '21 17:12 cscherrer