如何覆盖导入

时间:2016-08-27 19:53:29

标签: r namespaces httr r-package

My packageDESCRIPTION文件的Imports指令中包含httr

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

length.path exports an S3method

S3method(length,path)

它是defined as

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

在我的包中,我有一些对象,我分配了类&#34;路径&#34;至。每次我分配课程&#34;路径&#34;对于任何对象,无论我是否在对象上调用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的源代码,自我的软件包导入以来,我无法做到这一点。我怎么能绕过这个?

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

我的解决方案是添加.onLoad功能。感谢unclass想法的AEF's answer

#' @importFrom utils assignInNamespace
.onLoad = function(libname, pkgname) {
  length.path = function(obj) {
    return(length(unclass(obj)))
  }

  assignInNamespace('length.path', length.path, 'httr')
}

它在NOTE中引发R CMD check --as-cran,但我希望能够逃脱它。