如何从Imports中列出的R包中覆盖导出的函数

Nic*_*ite 6 namespaces r httr r-package

我的包DESCRIPTION文件httr在Imports指令中有:

Imports:
    httr (>= 1.1.0),
    jsonlite,
    rstudioapi
Run Code Online (Sandbox Code Playgroud)

httr 出口S3方法length.path.

S3method(length,path)
Run Code Online (Sandbox Code Playgroud)

它被定义为:

#' @export
length.path <- function(x) file.info(x)$size
Run Code Online (Sandbox Code Playgroud)

在我的包中,我有一些对象,我将类指定为"路径".每次我将类"path"分配给任何对象时,无论我是否调用length()该对象,都会将其打印到stdout:

Error in file.info(x) : invalid filename argument
Run Code Online (Sandbox Code Playgroud)

以下是每个人都可以运行的一些可重现的代码:

> 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
Run Code Online (Sandbox Code Playgroud)

我试过把它捕获try但是这不起作用:

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

thing = 1:5
thing = try(set_class(thing, 'path'), silent=TRUE)
Run Code Online (Sandbox Code Playgroud)

产量:

Error in file.info(x) : invalid filename argument
Run Code Online (Sandbox Code Playgroud)

我试图assignInNamespace覆盖这个功能:

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

assignInNamespace('length.path', base_length, 'httr')
thing = 1:5
class(thing) = 'path'
Run Code Online (Sandbox Code Playgroud)

但我明白了 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*_*AEF 1

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

length.path <- function(x) length(unclass(x))
Run Code Online (Sandbox Code Playgroud)

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