How to call the original function when overriding it

I want to override to make it first simplify the quantity’s unit before showing it. I don’t know how to call the original overriden function though. What I have tried:

@defonce origShow =
@eval Unitful function, mime::MIME"text/plain", x::Quantity)
    Main.origShow(io, mime, upreferred(x))
@eval Unitful function, mime::MIME"text/plain", x::Vector{<:Quantity})
    Main.origShow(io, mime, upreferred(x))

This code seems to cause an infinite loop and crashes Julia.

You can use invoke to call a more generic method of the same function:

julia> function foo(x)
         println("generic foo")
foo (generic function with 1 method)

julia> function foo(x::Int)
         invoke(foo, Tuple{Any}, x)  # Call the x::Any version of `foo`
         println("specific foo")
foo (generic function with 2 methods)

julia> foo(1)
generic foo
specific foo
1 Like

I want to call that exact method, not a more generic version.

invoke should be able to do that if you replace the Tuple{Any} bit with the types you are specifying.
I’m curious, though, why do you want to modify the function’s general behavior instead of using a new function like newshow(io, mime, x) =, mime, upreferred(x)) or just simplifying x = upreferred(x) wherever you can before calling

Then invoke would call my own newly defined function, no? The type signature of the new method is identical to its super method.

I don’t define a new function because I am trying to override how some values are displayed on the REPL. I don’t want to type upreferred(...) for everything.

Oh I see what you mean now. You wanted origShow = to “copy” the function so you can use the function name for something else. But origShow actually sticks with the name It works that way because when you dynamically change a function’s behavior i.e. by adding methods, you normally want methods that use that function to also change their behavior (method invalidation).

Your code just ended up being indirectly recursive, hence the suggestions to instead make another method with more specific types (to take precedence in dispatch) or a differently-named wrapper function. I think the only other straightforward way to make a different method is with a different number of arguments, like show(blah, io, mime, x) = show(io, mime, upreferred(x)). But I think you’re saying that the usual ways won’t work for this case because you’re not even calling this method directly, you’re trying to affect how the REPL decides to print something.

On 1.6 (or maybe only on master) you can use invoke_in_world for this:

julia> f(x) = print(x)
f (generic function with 1 method)

julia> w = Base.get_world_counter()

julia> g(x) = Base.invoke_in_world(w, f, x)
g (generic function with 1 method)

julia> f(x) = begin; print("new: "); g(x); end
f (generic function with 1 method)

julia> f(2)
new: 2

World age always spooked me, shouldn’t be too surprised it powers such witchcraft!

Thaanks! It’s cool stuff like this that makes me love Julia.