How to use trace() for function in parent or child environment?

0

Issue

I would like to debug functions from different environment than environmen from which I call trace() or debug(), but I don’t know how to refer to these functions.

fun1 <- function() {
  a <-  1
  a
}

fun2 <- function() {
  fun1 <- function(){
    b <- 2
    b
  }
  trace(fun1, browser, where = globalenv())
}

fun1()
fun2()
fun1()

Above I have prepared example where in child environment I’m calling trace() and want to insert browser() into the function defined in parent environment (in my example – global environment, but I’m looking for the solution taking into account any parent environment).

However, in my example browser() is inserted into fun1() which has b as a local variable, so not the function I wanted.

To summarize:

  1. How to refer to the function from any parent environment using trace()? So also from grandparent, grand grandparent etc.
  2. Is it also possible to refer to the function from child environment being in parent environment? If yes, how to do this?

Solution

This question was answered by Duncan Murdoch on R-help Mailing List. I’m posting the answer below:

You are being bitten by normal R scoping. While fun2 is executing, as
soon as it executes the fun1 assignment the name fun1 is bound to the
local function, so when you use fun1 in the first argument to trace(),
you get that one. It will ignore then "where" argument because it was
passed a function object. If you quote the name it will have to do a
lookup and it will use "where". So write fun2 like this:

fun2 <- function() {
   fun1 <- function(){
     b <- 2
     b
   }
   trace("fun1", browser, where = globalenv())
}

How can I refer to some function from the parent environment (not necessarily defined in the global environment) being in the child environment?

You could have used parent.frame() in place of globalenv() if you want a
function that was visible to the caller of fun2. If you want a function
that was defined with the same environment as fun2, you can usually use
environment(fun2), or parent.env(environment())

Can I refer to some function from the child environment being in the parent environment? I guess not, because of ephemerality?

Sometimes you can, but not usually. If fun2 had returned a value that
referenced the evaluation frame, you would be able to see the "b"
version of fun1 there. But yours didn’t. This one would:

fun2 <- function() {
   fun1 <- function(){
     b <- 2
     b
   }
   trace("fun1", browser, where = globalenv())
   environment()
}

Now if you do e <- fun2(), you’ll set the trace on the global fun1, but
e$fun1 will be the local one.

Source: https://stat.ethz.ch/pipermail/r-help/2021-December/473434.html

Answered By – gss

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave A Reply

Your email address will not be published.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More