在R(3.4.3)中,
在我将代码移到包中之前,我试图使代码更简洁。我正在努力寻找一种简单的方法来检查传递给环境中多个函数的实际参数,尤其是当其中一些参数具有默认值时。我的目标不是在每个函数中粘贴冗余代码,保持可读性,而不是遇到范围问题。这是一个例子(假设这些函数在同一个环境/脚本中):
当前代码
foo_add <- function(x, y = x, divisible = TRUE) {
if(missing(x) || !is.numeric(x)) stop("define x as a number")
if(!is.numeric(y)) y <- x
if(!is.logical(divisible)) stop("define divisible as TRUE or FALSE")
...}
foo_subtract <- function(x, y = x, divisible = TRUE) {
if(missing(x) || !is.numeric(x)) stop("define x as a number")
if(!is.numeric(y)) y <- x
if(!is.logical(divisible)) stop("define divisible as TRUE or FALSE")
...}
foo_divide <- function(x, y = x, divisible = TRUE) {
if(missing(x) || !is.numeric(x)) stop("define x as a number")
if(!is.numeric(y)) y <- x
if(!is.logical(divisible)) stop("define divisible as TRUE or FALSE")
...}
你可以看到我重复代码只是为了验证useR是否正确定义了参数。下面我添加了一个列表返回,以检查是否有效。我演绎了一个更清洁的版本:
所需代码
foo_add <- function(x, y = x, divisible = TRUE) {
do.call("check_args", mget(names(formals())))
list(x,y,divisible)
}
foo_subtract <- function(x, y = x, divisible = TRUE) {
do.call("check_args", mget(names(formals())))
list(x,y,divisible)
}
foo_divide <- function(x, y = x, divisible = TRUE) {
do.call("check_args", mget(names(formals())))
list(x,y,divisible)
}
check_args <- function(x,y,divisible) {
if(missing(x) || !is.numeric(x)) stop("define x as a number")
if(!is.numeric(y)) y <- x
if(!is.logical(divisible)) stop("define divisible as TRUE or FALSE")
}
基本上我想要做的是在控制默认参数和缺少参数时始终检查是否正确指定了实际参数。根据我的基本知识,我想为实际参数创建一个constructor-esk函数。我还希望不仅能够进行错误检查,还能修改实际的参数值并将它们返回到父函数以供使用(例如,像条件if(!is.numeric(y)) y <- x
)。
期望代码似乎有效,我只想确定,鉴于我对R编程有多新,我会考虑事情。具体来说,如果我修改check_args()
中的对象,则使用do.call
将它们传递给父函数。 有没有更简洁的方法来做这件事?