Skip to content

Instantly share code, notes, and snippets.

@yjunechoe
Last active March 5, 2022 08:15
Show Gist options
  • Save yjunechoe/6be820b5a191fe62fd8afbf83cf347c0 to your computer and use it in GitHub Desktop.
Save yjunechoe/6be820b5a191fe62fd8afbf83cf347c0 to your computer and use it in GitHub Desktop.
inner_fn <- function() {
cat("-- Entering Inner Function --\n")
# This step of the body is targeted by `at = 3L` in `trace()`
cat("-- Exiting Inner Function --\n")
return("inner_fn")
}
outer_fn <- function() {
cat("---- Entering Outer Function ----\n")
x <- inner_fn()
cat("---- Exiting Outer Function ----\n")
paste(x, "then outer_fn")
}
outer_fn()
#> ---- Entering Outer Function ----
#> -- Entering Inner Function --
#> -- Exiting Inner Function --
#> ---- Exiting Outer Function ----
#> [1] "inner_fn then outer_fn"
trace(what = inner_fn, at = 3L, tracer = quote({
all_frames <- sys.frames()
cur_frame <- all_frames[[sys.nframe()]]
first_to_cur_frame <- min(which(sapply(all_frames, function(f) identical(f, cur_frame))))
rlang::eval_bare(quote(return("highjacked!")), sys.frames()[[first_to_cur_frame - 1L]])
}))
#> [1] "inner_fn"
outer_fn()
#> ---- Entering Outer Function ----
#> -- Entering Inner Function --
#> Tracing inner_fn() step 3
#> [1] "highjacked!"
untrace(inner_fn)
outer_fn()
#> ---- Entering Outer Function ----
#> -- Entering Inner Function --
#> -- Exiting Inner Function --
#> ---- Exiting Outer Function ----
#> [1] "inner_fn then outer_fn"
@yjunechoe
Copy link
Author

yjunechoe commented Mar 4, 2022

https://twitter.com/yjunechoe/status/1499828109482205184?s=20&t=L0T4EG_o_YN5LJQbMsN5WQ

inner_fn <- function() {
    cat("-- Entering Inner Function --\n")
    # This step of the body is targeted by `at = 3L` in `trace()`
    cat("-- Exiting Inner Function --\n")
    return("inner_fn")
}

outer_fn <- function() {
    cat("---- Entering Outer Function ----\n")
    x <- inner_fn()
    cat("---- Exiting Outer Function ----\n")
    paste(x, "then outer_fn")
}

outer_fn()
#> ---- Entering Outer Function ----
#> -- Entering Inner Function --
#> -- Exiting Inner Function --
#> ---- Exiting Outer Function ----
#> [1] "inner_fn then outer_fn"

trace(what = inner_fn, at = 3L, tracer = quote({
    all_frames <- sys.frames()
    cur_frame  <- all_frames[[sys.nframe()]]
    first_to_cur_frame <- min(which(sapply(all_frames, function(f) identical(f, cur_frame))))
    rlang::eval_bare(quote(return("highjacked!")), sys.frames()[[first_to_cur_frame - 1L]])
}))
#> [1] "inner_fn"

outer_fn()
#> ---- Entering Outer Function ----
#> -- Entering Inner Function --
#> Tracing inner_fn() step 3
#> [1] "highjacked!"

untrace(inner_fn)

outer_fn()
#> ---- Entering Outer Function ----
#> -- Entering Inner Function --
#> -- Exiting Inner Function --
#> ---- Exiting Outer Function ----
#> [1] "inner_fn then outer_fn"

Created on 2022-03-04 by the reprex package (v2.0.1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment