# How to insert hooks into arbitrary places

**URL:** <https://discourse.julialang.org/t/how-to-insert-hooks-into-arbitrary-places/94841>\
**Category:** General Usage\
**Created:** [February 18, 2023, 3:37pm UTC](https://discourse.julialang.org/t/how-to-insert-hooks-into-arbitrary-places/94841 "2023-02-18T15:37:14Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lilith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lilith/32/27492_2.png) [@Lilith](https://discourse.julialang.org/u/Lilith)\
**Post date:** [February 18, 2023, 3:37pm UTC](https://discourse.julialang.org/t/how-to-insert-hooks-into-arbitrary-places/94841/1 "2023-02-18T15:37:14Z")

</div>

I want to log every call of `f(::T)`. I don’t know at design time what the implementation of `f(::T)` is, so I can’t reproduce it.

One idea is to save `m = which(f, Tuple{T})` and then insert a hook with `f(x::T) = (log(x); invoke_method(m, x)` and delete the hook with `Base.delete_method(which(f, Tuple{T})); Base.insert_method(m)`, but I don’t know how to `invoke_method` or `insert_method`.

How is this done in Julia?

---

<div class="post-metadata">

**Author:** ![kellertuer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kellertuer/32/220707_2.png) [@kellertuer](https://discourse.julialang.org/u/kellertuer)\
**Post date:** [February 18, 2023, 4:42pm UTC](https://discourse.julialang.org/t/how-to-insert-hooks-into-arbitrary-places/94841/2 "2023-02-18T16:42:52Z")

</div>

You could do that “the other way around”, write a decorator for F and use that instead of f?

```julia
struct LogFCall{F}
    f::F
end
function (f_l::LogFCall)(x)
    println("I do some logging")
    return f_l.f(x)
end
# A function f
f(x) = x+3
# but we use this function instead in all places
f_l = LogFCall(f)

```

then

```julia
julia> f_l(4)
I do some logging
7

```

and `f_l`would be what you use in all places you before used `f`. And sure you could write this functor also with a list of things to do that you can add or remove (instead of just doing a print doing set of functions then).

So in Hooks, `LogFCall` is a `HookMemory` around `f`.

Is that maybe something that helps?

---

<div class="post-metadata">

**Author:** ![Lilith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lilith/32/27492_2.png) [@Lilith](https://discourse.julialang.org/u/Lilith)\
**Post date:** [February 18, 2023, 9:14pm UTC](https://discourse.julialang.org/t/how-to-insert-hooks-into-arbitrary-places/94841/3 "2023-02-18T21:14:47Z")

</div>

That’s not what I’m looking for. I want this to be generic over arbitrary code and not require editing the downstream code to call my functions (e.g. when tracking `getindex`, I can’t exactly replace every call to `getindex` in the base library to `l_getindex`).

Wrapping the arguments with a decorator type is not what I’m looking for for similar reasons.

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [February 18, 2023, 11:49pm UTC](https://discourse.julialang.org/t/how-to-insert-hooks-into-arbitrary-places/94841/4 "2023-02-18T23:49:55Z")

</div>

Cassette helps?  
[https://julia.mit.edu/Cassette.jl/stable/overdub/](https://julia.mit.edu/Cassette.jl/stable/overdub/)

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [February 19, 2023, 1:00am UTC](https://discourse.julialang.org/t/how-to-insert-hooks-into-arbitrary-places/94841/5 "2023-02-19T01:00:01Z")

</div>

> [@Lilith](#):
>
> How is this done in Julia?

The boring answer is - we have Cassette.jl for that, but the caveat with that is tons and tons of invalidations, compile times and general dislike for magic solutions that reach deep into existing code without a controlling dispatch 🤷
