【问题标题】:Accessing the function that is being called from within the function访问从函数内部调用的函数
【发布时间】:2015-11-06 09:19:01
【问题描述】:

在函数中,我们如何才能可靠地返回包含函数本身的对象?

例如:

functionBuilder <- function(wordToSay) {
  function(otherWordToSay) {
    print(wordToSay)
    print(otherWordToSay)
    get(as.character(match.call()[[1]]))
  }
}

我可以像这样构建一个函数:

functionToRun &lt;- functionBuilder("hello nested world")

...并运行它...

functionToRun("A")
#[1] "hello nested world"
#[1] "A"
#
#function(otherWordToSay) {
#        print(wordToSay)
#        print(otherWordToSay)
#        get(as.character(match.call()[[1]]))
#      }
#<environment: 0x1e313678>

... 如您所见,functionToRun 返回自身。但是,如果我通过 sapply 调用 functionToRun,这种方法似乎会中断:

> sapply(LETTERS, functionToRun)
#[1] "hello nested world"
#[1] "A"
#Error in get(as.character(match.call()[[1]])) : object 'FUN' not found

我可以看到这是因为使用 sapply 时的实际调用是 FUN 但 FUN 在 pos = -1 时不存在(get 的默认值)。在该位置工作的代码如下所示:

get(as.character(match.call()[[1]]),envir = sys.frame(sys.parent()))

但是如果没有通过 sapply 调用该函数,则相同的代码将失败,因为 sys.frame(sys.parent())) 回退太远,最终引用了 R_GlobalEnv。

从文档 (R 3.2.2) 中,我预计 dynGet 可能会解决仅根据需要返回堆栈的问题。虽然这适用于函数的sapply 调用,但当函数被单独调用时它会失败。 (此外,它被标记为“有点实验性”)。相反,getAnywhere 似乎很有希望,但似乎不适用于 sapply 调用函数。

是否有可靠的方法来返回当前正在处理的函数,即适用于裸函数调用和 sapply 包装函数调用?

我现在正在做的是将获取函数的尝试包装在 tryCatch 中;但我有点不确定我是否可以相信get(as.character(match.call()[[1]]),envir = sys.frame(sys.parent())) 将适用于所有包装案例(不仅仅是 sapply)。所以,我正在寻找一种更合理的方法来解决这个问题。

可能相关的问题:

【问题讨论】:

    标签: r


    【解决方案1】:

    我不能保证这在所有情况下都有效,但看起来没问题:

    fun <- function(x) {
      print(x)
      y <- exp(x)
      print(y)
      sys.function(0)
    }
    
    fun(1)
    # [1] 1
    # [1] 2.718282
    # function(x) {
    #   print(x)
    #   y <- exp(x)
    #   print(y)
    #   sys.function(0)
    # }
    lapply(1:5, fun)[[3]]
    # [1] 1
    # [1] 2.718282
    # [1] 2
    # [1] 7.389056
    # [1] 3
    # [1] 20.08554
    # [1] 4
    # [1] 54.59815
    # [1] 5
    # [1] 148.4132
    # function(x) {
    #   print(x)
    #   y <- exp(x)
    #   print(y)
    #   sys.function(0)
    # }
    

    当然,我不明白你需要这个做什么。

    【讨论】:

    • 我认为它是非常通用的,但我正在使用它来实现类似于R.cache 的缓存层。所以,我想获取函数本身,以便我可以消化它并将其用作哈希的一部分来存储函数的结果,以保证缓存的结果与函数当前生成的结果相匹配。
    猜你喜欢
    • 2015-11-07
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多