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

时间:2022-06-29 17:00:11

I have multiple functions handing around arguments that may be missing.

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

e.g. i have

例如我有

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

with the interesting aspect that the only interaction of mytest(somearg) with the arg is that it tests if the argument isn’t missing:

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

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

subfunction then again tests if it’s missing and treats it accordingly:

子功能然后再次测试它是否丢失并相应地对待它:

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

the kicker is that, with somearg missing, this doesn’t work: matrix(somearg, cols = 2) throws

踢球者是这样的,有些缺失,这不起作用:矩阵(somearg,cols = 2)抛出

argument "somearg" is missing, with no default

参数“somearg”缺失,没有默认值

during debugging, i found the following:

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

  1. at the start of mainfunction, missing(somearg) returns TRUE
  2. 在mainfunction开始时,missing(somearg)返回TRUE
  3. in mytest, missing(somearg) returns TRUE
  4. 在mytest中,missing(somearg)返回TRUE
  5. insubfunction, missing(somearg) returns FALSE (!!!!)
  6. insubfunction,missing(somearg)返回FALSE(!!!!)

therefore the matrix branch is hit, but in reality, somearg is missing, so it fails…

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

wat.

笏。

1 个解决方案

#1


1  

the @BenBolker way:

@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
}

Another way, using explicit missing argument

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

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
}

A third way, using plain missing arg passing:

第三种方式,使用普通的缺失arg传递:

    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
    }

#1


1  

the @BenBolker way:

@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
}

Another way, using explicit missing argument

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

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
}

A third way, using plain missing arg passing:

第三种方式,使用普通的缺失arg传递:

    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
    }