强制评估所有惰性函数参数

时间:2017-10-31 17:03:08

标签: r

这是我的功能:

f <- function(a, b, ...){
  c(as.list(environment()), list(...))
}

如果我致电f(a = 2),则不会引发任何错误,但缺少b。我希望在这种情况下出错:

Error in f(a = 2) : argument "b" is missing, with no default

我必须添加哪些 动态 和高效代码,以便引发此错误?我正在考虑以下内容:force(as.symbol(names(formals())))

注意:如果您想知道我为什么需要这种功能:这是一种标准化列表类型的方法。此类列表必须包含ab,以及其他可能的密钥。我也可以玩对象......

解决方案:请参阅下面的Carl的回答或评论。

f <- function(a, b, ...){
  sapply(ls(environment()), get, envir = environment(), inherits = FALSE)
  c(as.list(environment()), list(...))
}

f <- function(a, b, ...){
  stopifnot(all(setdiff(names(formals()), '...') %in% names(as.list(match.call()[-1]))))
  c(as.list(environment()), list(...))
}

1 个答案:

答案 0 :(得分:1)

一个想法......首先检查匿名存在于任何函数中的所有参数...意味着无论函数如何,将参数放入没有预设要求的列表中:

#' A function to grab all arguments of any calling environment.. ie.. a function
#' 
#' 
#' \code{grab.args}
#' 
grab.args <- function() {
  envir <- parent.frame()
  func <- sys.function(-1)
  call <- sys.call(-1)
  dots <- match.call(func, call, expand.dots=FALSE)$...
  c(as.list(envir), dots)
}

然后,在你使用它的任何函数中......将初始参数存储在列表does_have上,然后找到在should_have环境中预定义的所有参数,循环遍历列表匹配名称,并查找是否有任何缺失的值...如果有...创建错误的名称,如果没有...做你的事情...

#' As an example
#' 
f <- function(a, b, ...){
  does_have <- grab.args()
  should_have <- ls(envir = environment())
  check_all <- sapply(should_have, function(i){
    !nchar(does_have[[i]])
  })
  if(any(mapply(isTRUE, check_all))){
    need_these <- paste(names(which(mapply(isTRUE,check_all))), collapse = " and ")
    cat(sprintf('Values needed for %s', need_these))
  }else {
    does_have
  }

}

原因输出......

> f(mine = "yours", a = 3)
Values needed for b
> f(b = 12)
Values needed for a
> f(hey = "you")
Values needed for a and b

编辑以抛出实际错误...

f <- function(a,b,...){
    Filter(missing, sapply(ls(environment()), get, environment()))
}


> f(a = 2, wtf = "lol")
 Error in FUN(X[[i]], ...) : argument "b" is missing, with no default