我想包含一个带有我们正在编写的R包函数的闭包。函数(及其兄弟)将在其环境中拥有数据,执行输入与数据的比较,并返回结果。为了说明,考虑一个内置电话目录的函数:用数字查询,函数返回一个名字。
这个函数将被我们的R包中的其他几个函数称为帮助器,因此一旦加载包就必须存在。我们希望函数在包环境中可用,就像任何其他函数一样。
我应该通过.onLoad()中的工厂函数创建它并将它()分配给包环境吗?我可以把它作为.RDS发货吗?或RData,或者这违反了“二进制可执行代码”的CRAN政策?还是有不同的,规范的方式?代码和数据(或RDS / RData)将在包目录结构中的哪个位置?
(我看到有关如何记录闭包的问题已经讨论过here)。
答案 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;据我所知。
R/aaa.R
中,以确保在关闭之前加载它。inst/extdata/
文件夹。R/
:将闭包定义为只返回任何内容的普通函数。这是必要的,因此函数在包命名空间中正确导出和已知。立即调用工厂函数创建闭包并覆盖原始定义。注意:仅仅将数据作为参数引入工厂函数是不够的,实际上需要在定义闭包之前访问它。为什么?这是因为延迟加载实际上已经将数据加载到您需要的环境中,除非您访问它。这就是全部。简介:为闭包创建一个存根,然后用工厂函数的返回值覆盖它。