R懒惰的评价悖论(R bug?)

fly*_*eep 10 r lazy-evaluation promise

我有多个函数处理可能缺少的参数.

我有

mainfunction <- function(somearg) {
    mytest(somearg)
    fun <- function() { subfunction(somearg) }
    fun()
}
Run Code Online (Sandbox Code Playgroud)

有趣mytest(somearg)的是,与arg 的唯一交互是它测试参数是否没有丢失:

mytest = function(somearg) {
    print(missing(somearg))
}
Run Code Online (Sandbox Code Playgroud)

subfunction 然后再次测试它是否缺失并相应地对待它:

subfunction = function(somearg) {
    if (missing(somearg))
        somearg = NULL
    else
        somearg = matrix(somearg, cols = 2)
    # somearg is used here…
}
Run Code Online (Sandbox Code Playgroud)

踢球者是因为somearg失踪,这不起作用:matrix(somearg, cols = 2)投掷

参数"somearg"缺失,没有默认值

在调试过程中,我发现了以下内容:

  1. 在开始时mainfunction,missing(somearg)返回TRUE
  2. 在mytest,missing(somearg)返回TRUE
  3. in subfunction,missing(somearg)return FALSE(!!!!)

因此matrix分支被击中,但实际上somearg 是缺失的,所以它失败了......

笏.

Kar*_*ner 1

@BenBolker 的方式:

mainfunction <- function(somearg = NULL) {
    mytest(somearg)
    fun <- function() { subfunction(somearg) }
    fun()
}

mytest = function(somearg) {
    print(is.null(somearg))
}

subfunction = function(somearg) {
    if (is.null(somearg))
        somearg = 1:10
    else
        somearg = matrix(somearg, ncol = 2)
   somearg
}
Run Code Online (Sandbox Code Playgroud)

另一种方法,使用显式缺失参数

mainfunction <- function(somearg) {
    is_missing <- missing(somearg)
    mytest(is_missing)
    fun <- function() { subfunction(somearg, is_missing) }
    fun()
}
mytest = function(x) {  print(x) }
subfunction = function(somearg, is_arg_missing) {
    if (is_arg_missing)
        somearg = 1:10
    else
        somearg = matrix(somearg, ncol = 2)
   somearg
}
Run Code Online (Sandbox Code Playgroud)

第三种方法,使用简单的缺失参数传递:

    mainfunction <- function(somearg) {
        is_missing <- missing(somearg)
        mytest(somearg)
        fun <- function() { 
          if (is_missing) subfunction() else 
              subfunction(somearg) 
        }
        fun()
    }

    mytest = function(somearg) {
        print(missing(somearg))
    }

    subfunction = function(somearg) {
        if (missing(somearg))
            somearg = 1:10
        else
            somearg = matrix(somearg, ncol = 2)
       somearg
    }
Run Code Online (Sandbox Code Playgroud)