如果使用多个包,在何处以及如何定义泛型函数

时间:2016-04-26 12:36:02

标签: r generics

我知道有相关帖子,但答案不足。所以请认真回答这个问题。

有两个软件包(“keithley”和“xantrex”)可控制两个不同的硬件设备。因此,两者彼此独立。每个都必须单独初始化。所以我写了两个方法

init.keithley(inst,...) # in keythley package

init.xantrex(inst,...) # in xantrex package

用于通用S3函数init(inst,...)。我试图在keithley包和xantrex包中声明泛型函数,但是一旦加载了后者并且找不到更多的方法,它就会被屏蔽掉。

我尝试的是.onAttach() - hook

.onAttach <- function(libname, pkgname)
{
  if(!exists("init"))
    eval(expression(init <- function(inst,...) UseMethod("init")),envir = .GlobalEnv)
}

但是有了这个,就无法评估包命名空间中的init()函数。这可以通过选项envir = environment()进行校对,但这不起作用。我也尝试了setGenericS3()setGeneric(),结果总是相同。 “脏”的解决方案可能是定义第三个包并导入它,但必须有一个干净的方法来执行此操作。

我应该在哪里以及如何定义泛型函数?

1 个答案:

答案 0 :(得分:0)

以下是解决方案:

据我所知,附加包有三个环境(例如"package:Xantrex""namespace:Xantrex""imports:Xantrex")这些内容的不同含义在此详细解释:Advanced R

现在,我们必须测试泛型函数init()是否已经存在,如果不是,我们必须在适当的环境中初始化它。以下代码将为我们做到这一点。

.onAttach <- function(libname, pkgname)
{
  if(!exists("init",mode = "function"))
    eval(expression(init <- function(inst,...) UseMethod("init")),envir = as.environment("package:Xantrex"))
}

.onAttach - hook,是保证初始化不同命名空间所必需的。与.onLoad - 钩形成对比,为时尚早。提到表达式是在package:Xantrex环境中进行评估的,因此通用在搜索路径中变得可见。

请注意,您的NAMESPACE文件将export(init.xantrex) S3method(init,xantrex)。后者将导致错误,因为在构建包时,方法init.xantrex()的泛型不存在。

最佳! 马丁