我正在尝试屏蔽包中的函数调用的函数。
作为一个可重现(我认为)的例子,看看函数 isTRUE
:
function (x)
identical(TRUE, x)
假设出于某种原因我想要
identical
永远返回 "foobar"
,因此 isTRUE
总是会返回“foobar”:# try override identical
identical <- function(...) { return('foobar') }
identical(TRUE, 'a') # 'foobar', as expected
现在我打电话
isTRUE
,希望调用identical
在该函数中将访问我的屏蔽版本,但它不会:isTRUE('a') # hope that this will return 'foobar'
# [1] FALSE
所以一般来说,我如何暂时导致从打包函数中调用的函数返回不同的东西?
语境
我的包中有一个函数:
myFunc <- function(...) {
if (!require(rgdal)) {
stop("You do not have rgdal installed")
}
# ...
}
我想测试一下,如果没有安装 rgdal,该函数会抛出错误。
但是,我确实安装了 rgdal。我要
myFunc
认为它不是(暂时),所以我试图做:require <- function(...) { return(FALSE) }
调用前
myFunc
希望它会失败。然而,似乎myFunc
没有被这个欺骗,仍然打电话 base::require
而不是我的 require
.(是的,这似乎是一件微不足道的事情,因为如果我没有安装 rgdal,
myFunc
肯定会抛出错误,但假设现在条件更复杂,我想以相同的方式进行测试 - 我的问题仍然存在站立)
最佳答案
您可以以编程方式创建一个函数
foo <- function(...) if(!require('MASS')) stop('foo')
testfun <- function(fun){
require <- function(...) FALSE
fff <- function(){}
formals(fff) <- formals(fun)
body(fff) <- body(fun)
fff
}
testfoo <- testfun('foo')
require
定义为 testfun
现在创建函数时。foo()
## Loading required package: MASS
detach(package:MASS)
testfoo()
# Error in testfoo() : foo
你可以用
local
做类似的事情,但我认为它会更困惑例如
testfoo2 <- local({
require <- function(...) FALSE
foo <- function(...) if(!require('MASS')) stop('foo')
})
testfoo2()
## Error in testfoo2() : foo
(来自数学咖啡 - 基于此答案的后续行动)。
我能够定义一个函数:
overrideIn <- function(f, ...) {
overrides <- list(...)
nms <- names(overrides)[names(overrides) != '']
# stub out the functions
for (nm in nms) {
assign(nm, overrides[[nm]])
}
# copy over f
fff <- function () {}
formals(fff) <- formals(f)
body(fff) <- body(f)
return(fff)
}
这样我就可以做
f <- overrideIn(myFunc, require=function (...) FALSE)
现在当我打电话时
f
它具有 require
的覆盖版本在里面,所以我可以做(使用梦幻般的 testthat 包):expect_that(f(), throws_error('You do not have rgdal installed'))
一个稍微简洁的 overide 函数版本(再次是 mnel)
overRideIn2 <- function(fun,...){
e <- environment()
.list <- list(...)
ns <- nchar(names(.list))>0L
list2env(.list[ns], envir = e)
fff <- as.function(as.list(fun))
}
关于R - 故意屏蔽包函数中的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15262084/