如何在R-package中包含一个闭包?

时间:2017-03-23 05:10:09

标签: r r-package

我想包含一个带有我们正在编写的R包函数的闭包。函数(及其兄弟)将在其环境中拥有数据,执行输入与数据的比较,并返回结果。为了说明,考虑一个内置电话目录的函数:用数字查询,函数返回一个名字。

这个函数将被我们的R包中的其他几个函数称为帮助器,因此一旦加载包就必须存在。我们希望函数在包环境中可用,就像任何其他函数一样。

我应该通过.onLoad()中的工厂函数创建它并将它()分配给包环境吗?我可以把它作为.RDS发货吗?或RData,或者这违反了“二进制可执行代码”的CRAN政策?还是有不同的,规范的方式?代码和数据(或RDS / RData)将在包目录结构中的哪个位置?

(我看到有关如何记录闭包的问题已经讨论过here)。

2 个答案:

答案 0 :(得分:1)

如果包用户稍后调用工厂函数

但是我们仍然希望返回的闭包在包内(例如,如果我们不希望它被工厂以外的任何东西更改,可以从包中可靠地访问,记录等等。):

# exported function (visible to user)
# everything this function does is 'outsourced'
# to a non-exported function that we can overwrite with the factory:

visible_function(...){
   hidden_function(...)
}
# not exported function (invisible to the user)
# called by the visible function
# fails unless factory is called first
hidden_function(x){
 stop("call factory_fun() before you can use visible_function()")
}

# exported function, visible to the user.
# changes the hidden function called by the visible function
factory_function(x){
  produced_function<-function(){
     print(paste(x, "is an object forever stored in my namespace!"))
  }
   assignInNamespace("hidden_function",
                     produced_function,
                     ns="myPackageName")
}

请注意,R CMD检查会在assignInNamespace上抛出一条注释,因此CRAN不会轻易接受此解决方案

答案 1 :(得分:0)

为了任何绊倒这个问题的人的利益。我最终解决的解决方案涉及几个步骤,但是&#34;清洁&#34;据我所知。

  1. 将工厂函数放在文件R/aaa.R中,以确保在关闭之前加载它。
  2. 将闭包使用的数据放入标准inst/extdata/文件夹。
  3. 将带有闭包名称和正确文档字符串的文件放入R/:将闭包定义为只返回任何内容的普通函数。这是必要的,因此函数在包命名空间中正确导出和已知。立即调用工厂函数创建闭包并覆盖原始定义。注意:仅仅将数据作为参数引入工厂函数是不够的,实际上需要在定义闭包之前访问它。为什么?这是因为延迟加载实际上已经将数据加载到您需要的环境中,除非您访问它。
  4. 这就是全部。简介:为闭包创建一个存根,然后用工厂函数的返回值覆盖它。