如何从导入中列出的R包中覆盖导出的功能

妮可·怀特

我包DESCRIPTION文件httr在其Imports指令中包含:

Imports:
    httr (>= 1.1.0),
    jsonlite,
    rstudioapi

httr 为导出S3方法length.path

S3method(length,path)

它的定义为

#' @export
length.path <- function(x) file.info(x)$size

在我的程序包中,有一些对象,我将其分配给“路径”类。每当我将“路径”类分配给任何对象时,无论我是否调用length()过该对象,它都将打印到stdout:

Error in file.info(x) : invalid filename argument

这是每个人都可以运行的可复制代码:

> sessionInfo()
R version 3.3.1 (2016-06-21)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.11.5 (El Capitan)

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] tools_3.3.1

> thing = 1:5
> class(thing) = 'path'

> requireNamespace('httr')
Loading required namespace: httr

> sessionInfo()
R version 3.3.1 (2016-06-21)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.11.5 (El Capitan)

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] httr_1.2.1  R6_2.1.2    tools_3.3.1

> thing = 1:5
> class(thing) = 'path'
Error in file.info(x) : invalid filename argument

我试着将其捕获到中,try但这不起作用:

set_class = function(obj, c) {
  class(obj) = c
  return(obj)
}

thing = 1:5
thing = try(set_class(thing, 'path'), silent=TRUE)

产量:

Error in file.info(x) : invalid filename argument

我试图assignInNamespace重写该功能:

base_length = function(obj) {
  return(base::length(obj))
}

assignInNamespace('length.path', base_length, 'httr')
thing = 1:5
class(thing) = 'path'

但是我明白了 Error: evaluation nested too deeply: infinite recursion / options(expressions=)?

当我httr在包中使用函数时,会与它们一起使用,httr::function因此我不确定该length.path函数如何泄漏到我的名称空间中并覆盖基本长度函数。我还尝试@importFrom httr function对使用的每个函数(而不是使用的函数)进行显式显示httr::function但这也不起作用。

我也发现了这一点:

https://support.bioconductor.org/p/79059/

但是解决方案似乎是编辑的源代码httr,因为我的程序包将其导入,所以我无法这样做。我该如何解决?

AEF

一种可能是length.path()在自己的程序包中创建一个函数如果path-objects的基本类型与您兼容,则base::length()可以对其进行取消分类以避免无限递归:

length.path <- function(x) length(unclass(x))

但是,与直接调用相比,这可能会比较慢,base::length()因为它会复制对象并需要两次分派方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章