访问R中函数的执行环境

时间:2017-02-06 09:26:25

标签: r function environment execution

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

prepare = function() {
    f = function(x) x+1
    g = function(x) x+2
}

当然,一旦函数执行函数f和g就不再可用了。它们在执行环境“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
}

有没有办法实现这一目标?也就是说,“准备”会影响调用环境,而不是它的执行环境吗?

编辑:

找到了一个使用body()的解决方法,它允许访问函数内的表达式,并从中构建新的表达式,因此我根据“prepare”函数的“body”构建了一个新函数,并且“原始的“功能。正如我所想的那样,真正的解决方案是使用“方面取向”。但遗憾的是R不是面向方面的语言。也许是一个新包装的想法: - )

3 个答案:

答案 0 :(得分:0)

如果您稍微修改prepare功能:

prepare = function() {
    f = function(x) x+1
    g = function(x) x+2
    return(list(f,g))
}

您可以访问以下功能:

prepare()[[1]](25)

# [1] 26

或者你可以使用<<-,它将功能放到全球环境中:

prepare = function() {
     f <<- function(x) x+1
     g <<- function(x) x+2
 }

答案 1 :(得分:0)

> 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

很长一段时间后编辑

我不得不为自己回来......

Process.Start(@"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe");
Process.Start(@"C:\Program Files (x86)\Mozilla Firefox\firefox.exe");
Process.Start(@"C:\Program Files\Internet Explorer\iexplore.exe");

答案 2 :(得分:0)

利用environment(fun)返回函数的封闭环境这一事实(该函数定义了函数查找对象的方式),environment()的以下用法使您可以访问{{ 1}}:

prepare()

产生:

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 函数返回一个函数(在这种情况下,函数prepare()在最后一行中已定义g(),因此返回 ),这意味着对prepare()environment())返回的对象上的prepare()的调用检索了fun_returned_by_prepare中定义的函数g(),恰好是prepare()的执行环境!

如果返回的prepare()值不是函数,则上述代码将不再起作用。

在旁注中,如果以下内容对于您可能需要的其他应用程序很方便:我编写了一个名为envnames的程序包,除此以外,它还允许您通过函数的执行环境来检索该函数的执行环境。名称(prepare())。但是,为了使它起作用,该函数必须是调用get_fun_env()的位置的调用堆栈的一部分,不幸的是,在上面的示例中情况并非如此。