0

I am trying to create a decorator in R that when used inside of another function will use the calling environment of that function as parent. I believe this can be achieved using eval() but I am having difficulties with the implementation.

This is what I got so far:

library(rlang)

###Decorator definition
dynamicCall <- function(decorated) {

  dynamicEnv <- new.env(parent = parent.frame())
  
  attach(dynamicEnv)
  
  eval(decorated, enclos = dynamicEnv)
  
  print('parents in dynamicCall')
  print(env_parents(dynamicEnv))
}



###Function to be decorated
f <- function() {
  print('parents in f')
  print(env_parents(environment()))
}


###Function to be called in
g <- function() {
  print('calling environment')
  print(environment())
  dynamicCall(f())
}

g()

And this is the output:

[1] "calling environment"
<environment: 0x00000211a91ff840>
[1] "parents in f"
[[1]] $ <env: global>
[1] "parents in dynamicCall"
[[1]]   <env: 0x00000211a91ff840>
[[2]] $ <env: global>

I don't understand why "parents in f" is different than "parents in dynamicCall". The enclosing environment should be dynamicEnv so the parents list should be the same? I'll be grateful for any help!

edit: adding the library

kemoT
  • 1
  • 2
  • 1
    Your code does not run. Maybe you are using some package but the library call is missing. f is defined in the global environment so calling parent.env(environment()) from within it gives the global environment whereas DynamicEnv is defined to have the caller of DynamicCall, i.e. the active environment when g runs, as its parent environment. – G. Grothendieck Jun 05 '23 at 13:31
  • Sorry, I updated the beggining of the code with library(rlang). Regarding your response: f is ran with eval(decorated, enclos = dynamicEnv), so I would expect it to have DynamicEnv as the parent environment. Is that not what 'enclos=' does? Documentation suggests that. – kemoT Jun 05 '23 at 13:51
  • 3
    Running f in a different environment does not change its environment. The environment of a function is part of the function definition and you would have to change f itself, i.e. environment(f) <- e where e is some environment. Note that if f depends on objects in its original environment the new function may no longer run properly. – G. Grothendieck Jun 05 '23 at 13:56
  • Suggest you compare running parent.env(environment()) and parent.frame() within your functions. and also look at environment(f),, etc. – G. Grothendieck Jun 05 '23 at 13:59
  • Thank you, I'll try a different way to do this then! – kemoT Jun 05 '23 at 14:02
  • Maybe this existing question is what you are trying to get at? https://stackoverflow.com/questions/12279076/r-specify-function-environment – MrFlick Jun 05 '23 at 14:10

0 Answers0