Is there a way to preserve overwritten method?

I was thinking about switch proposal

We have complex info in REPL about character:

julia> 'a'
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

If I want to avoid it I could do

julia> import Base.show

julia> show(io::IO, ::MIME{Symbol("text/plain")}, c::Char) = show(io, c)
show (generic function with 296 methods)

julia> 'a'
'a'

but if I want to have possibility to switch it on I need to remember old functionality. This doesn’t work:

julia> oldfnc(io::IO, m::MIME{Symbol("text/plain")}, c::Char) =  show(io, m, c);

julia> oldfnc(stdout, MIME{Symbol("text/plain")}(), 'a')
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
julia> import Base.show

julia> show(io::IO, ::MIME{Symbol("text/plain")}, c::Char) = show(io, c)
show (generic function with 296 methods)

julia> oldfnc(stdout, MIME{Symbol("text/plain")}(), 'a')
'a'

this naive experiment doesn’t work either

julia> mm = collect(methods(show, [IO, MIME{Symbol("text/plain")}, Char]))[1]
show(io::IO, ::MIME{Symbol("text/plain")}, c::T) where T<:AbstractChar in Base at char.jl:281

julia> mm('a')
ERROR: MethodError: objects of type Method are not callable

Interesting. Do you know what function is being called when we put 'a' into the REPL?

Because Base.show is not the function out side of 'a'

julia> Base.show('a')
'a'

julia> 'a'
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

julia> dump('a')
Char 'a'

julia> eval('a')
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

julia> dump(eval('a'))
Char 'a'

It is Base.show , but it have more than 200 methods, so you need to call proper one :slight_smile:

Try this:

julia> show(stdout, MIME{Symbol("text/plain")}(), 'a')
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

BTW you could also look at source code:

julia> @less show(stdout, MIME{Symbol("text/plain")}(), 'a')

It’s pretty easy with Revise & Rebugger:

julia> using Revise, Rebugger

julia> m = @which show(stdout, MIME("text/plain"), 'a')
show(io::IO, ::MIME{Symbol("text/plain")}, c::T) where T<:AbstractChar in Base at char.jl:281

julia> ex = Revise.get_def(m)
[ Info: tracking Base
:(function show(io::IO, ::@MIME_str("text/plain"), c::T) where T <: AbstractChar
      show(io, c)
      if !(ismalformed(c))
          print(io, ": ")
          if isoverlong(c)
              print(io, "[overlong] ")
              u = decode_overlong(c)
              c = T(u)
          else
              u = codepoint(c)
          end
          h = string(u, base=16, pad=if u ≤ 0xffff
                          4
                      else
                          6
                      end)
          print(io, if isascii(c)
                  "ASCII/"
              else
                  ""
              end, "Unicode U+", h)
      else
          print(io, ": Malformed UTF-8")
      end
      abr = Unicode.category_abbrev(c)
      str = Unicode.category_string(c)
      print(io, " (category ", abr, ": ", str, ")")
  end)

julia> Core.eval(Base, convert(Expr, Rebugger.rename_method(ex, :oldshow, nothing)))
oldshow (generic function with 1 method)

julia> Base.oldshow(stdout, MIME("text/plain"), 'a')
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
2 Likes

Hmm. Maybe I need a newer (or older snapshot)…

  | | |_| | | | (_| |  |  Version 1.1.0-DEV.542 (2018-10-25)
 _/ |\__'_|_|_|\__'_|  |  Commit 36e21d47b5 (21 days old master)

julia> using Revise; using Rebugger

julia> m = @which show(stdout, MIME("text/plain"), 'a')
show(io::IO, ::MIME{Symbol("text/plain")}, c::T) where T<:AbstractChar in Base at char.jl:292

julia> ex = Revise.get_def(m)
[ Info: tracking Base
ERROR: KeyError: key "/home/lapeyre/.local/julias/julia-1.1.0-DEV.542/share/julia/base/char.jl" not found
Stacktrace:
 [1] getindex at ./dict.jl:478 [inlined]
 [2] macro expansion at ./logging.jl:313 [inlined]
 [3] #get_def#53(::Set{String}, ::Function, ::Method) at /home/lapeyre/.julia/packages/Revise/xO23U/src/Revise.jl:628
 [4] get_def(::Method) at /home/lapeyre/.julia/packages/Revise/xO23U/src/Revise.jl:606
 [5] top-level scope at none:0

Seems like a path issue; I haven’t had anyone report one of those in a while. Please open a Revise issue and report your findings while following these tips.

1 Like