在R中访问函数的执行环境

在R中访问函数的执行环境,r,function,environment,execution,R,Function,Environment,Execution,我有一个为程序的其余部分“准备”东西的功能。例如,以下函数定义了两个函数: prepare = function() { f = function(x) x+1 g = function(x) x+2 } 当然,一旦函数执行,函数f和g就不再可用。它们是在“prepare”的执行环境中定义的,一旦函数完成执行,它就消失了 我的问题是,有没有办法保持或访问该执行环境 这种情况是,我从外部获取“prepare”函数,因此无法编辑其代码,我希望以以下方式执行它并使用它所做的任何事情:

我有一个为程序的其余部分“准备”东西的功能。例如,以下函数定义了两个函数:

prepare = function() {
    f = function(x) x+1
    g = function(x) x+2
}
当然,一旦函数执行,函数f和g就不再可用。它们是在“prepare”的执行环境中定义的,一旦函数完成执行,它就消失了

我的问题是,有没有办法保持或访问该执行环境

这种情况是,我从外部获取“prepare”函数,因此无法编辑其代码,我希望以以下方式执行它并使用它所做的任何事情:

my_function = function(prepare) {
    # the prepare function is supplied by the user
    prepare()  #this should define the f and g functions as above
    f(3)   # this wouldn't work normally, since f is defined inside prepare
}
有没有办法做到这一点?也就是说,使“prepare”影响调用环境,而不是其执行环境

编辑:


找到了一个使用body()的变通方法,它允许访问函数内部的表达式,并从中构建新的表达式,因此我基于“prepare”函数和“original”函数的“body”构建了一个新函数。正如我所想,真正的解决办法是使用“面向方面”。但不幸的是,R不是面向方面的语言。可能是一个新软件包的想法:-)

如果您稍微修改一下
prepare
函数:

prepare = function() {
    f = function(x) x+1
    g = function(x) x+2
    return(list(f,g))
}
您可以访问如下功能:

prepare()[[1]](25)

# [1] 26

或者您可以使用
使用
environment(fun)
返回函数的封闭环境(定义函数如何查找对象)这一事实,下面使用
environment()
可以访问
prepare()
中定义的函数:

这将产生:

Result of calling function f(3) defined in function prepare(): 4 
Result of calling function g(3) defined in function prepare(): 5
但是,这仅是因为函数
prepare()
返回一个函数(在本例中,函数
g()
,该函数在
prepare()
的最后一行定义并因此返回),这意味着对
prepare()
返回的对象的
environment()
调用(\u prepare
返回的
fun\u)检索
prepare()
中定义的函数
g()
的封闭环境,它恰好是
prepare()
的执行环境

如果
prepare()
的返回值不是函数,则上述代码不再有效


另一方面,如果您可能有其他应用程序,那么下面的内容会很方便:我编写了一个名为的包,它允许您通过函数名检索函数的执行环境(
get\u fun\u env()
)。但是,为了使其正常工作,该函数必须是调用
get\u fun\u env()
的调用堆栈的一部分,不幸的是,在上面的示例中并非如此。

如我所说,我无法编辑“prepare”函数。它是由其他人编写的,并作为我的代码的参数提供。因此您的建议不适用。您如何确保其他人的函数中包含
f
g
?同样,您可以要求他们返回列表或更改范围或..编写
f
g
在一个单独的文件中,然后您可以调用
myEnvsee my edit。最终,我使用body()找到了一个解决方法。在我的场景中,由用户提供“prepare”函数以及稍后在代码中使用它的方法,但代码必须在我创建的环境中执行(并向其中添加更多用户无法控制的内容)。不幸的是,我无法更改“prepare”函数,该函数由其他人提供并作为参数传递。
>prepare<-function() return(list(f=function(x) x+1, g=function(x) x+2))
> p<-prepare()
> p$f(1)
[1] 2
> p$g(1)
[1] 3
> prepare
function(x) { p = function(x) 5*x; q= function(x) x^2 }
> with( new.env ( eval( parse(text=deparse(body(prepare))) ) ) , { print(p(5)); print(q(2))} )
[1] 25
[1] 4
prepare = function() {
  f = function(x) x+1
  g = function(x) x+2
}

my_function = function(preparefun) {
  # We call the prepare() function supplied by the user
  # that defines functions f() and g() and store its returned value
  # (WHICH IS A FUNCTION)
  fun_returned_by_prepare = preparefun()
  cat("Result of calling function f(3) defined in function prepare():", environment(fun_returned_by_prepare)$f(3), "\n")
  cat("Result of calling function g(3) defined in function prepare():", environment(fun_returned_by_prepare)$g(3), "\n")
}

my_function(prepare)
Result of calling function f(3) defined in function prepare(): 4 
Result of calling function g(3) defined in function prepare(): 5