如何覆盖导入中列出的 R 包中的导出函数
How to override exported function from R package listed in Imports
My package 的 DESCRIPTION
文件在其 Imports 指令中有 httr
:
Imports:
httr (>= 1.1.0),
jsonlite,
rstudioapi
httr
exports an S3method 对于 length.path
.
S3method(length,path)
它是 defined as:
#' @export
length.path <- function(x) file.info(x)$size
在我的包中,我有我分配给 class "path" 的对象。每次我将 class "path" 分配给任何对象时,无论我是否曾在该对象上调用 length()
,都会打印到标准输出:
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
的源代码,我不能这样做,因为我的包导入了它。我该如何解决这个问题?
一种可能是在您自己的包中创建一个函数 length.path()
。如果你的 path
-objects 的基类型与 base::length()
兼容,你可以取消它的类以避免无限递归:
length.path <- function(x) length(unclass(x))
但是,与直接调用 base::length()
相比,这可能会比较慢,因为它会复制对象并需要两次方法分派。
我的解决方案是添加一个 .onLoad
函数。感谢 的 unclass
想法。
#' @importFrom utils assignInNamespace
.onLoad = function(libname, pkgname) {
length.path = function(obj) {
return(length(unclass(obj)))
}
assignInNamespace('length.path', length.path, 'httr')
}
它在 R CMD check --as-cran
中引发了 NOTE
,但我希望能够摆脱它。
My package 的 DESCRIPTION
文件在其 Imports 指令中有 httr
:
Imports:
httr (>= 1.1.0),
jsonlite,
rstudioapi
httr
exports an S3method 对于 length.path
.
S3method(length,path)
它是 defined as:
#' @export
length.path <- function(x) file.info(x)$size
在我的包中,我有我分配给 class "path" 的对象。每次我将 class "path" 分配给任何对象时,无论我是否曾在该对象上调用 length()
,都会打印到标准输出:
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
的源代码,我不能这样做,因为我的包导入了它。我该如何解决这个问题?
一种可能是在您自己的包中创建一个函数 length.path()
。如果你的 path
-objects 的基类型与 base::length()
兼容,你可以取消它的类以避免无限递归:
length.path <- function(x) length(unclass(x))
但是,与直接调用 base::length()
相比,这可能会比较慢,因为它会复制对象并需要两次方法分派。
我的解决方案是添加一个 .onLoad
函数。感谢 unclass
想法。
#' @importFrom utils assignInNamespace
.onLoad = function(libname, pkgname) {
length.path = function(obj) {
return(length(unclass(obj)))
}
assignInNamespace('length.path', length.path, 'httr')
}
它在 R CMD check --as-cran
中引发了 NOTE
,但我希望能够摆脱它。