【问题标题】:Storing input value to check wether postcondition holds true when applying Design-by-Contract存储输入值以在应用按合同设计时检查后置条件是否成立
【发布时间】:2018-10-27 20:58:15
【问题描述】:

我经常使用assertthat 包来检查函数中的后置条件。在阅读有关按合同设计的想法的更多信息时,我偶然发现了将输出与输入值进行比较的想法。

最简单的例子如下:

toggle <- function(x)!x

可以立即声明x == !old_x 必须始终为真。 (old_x 代表评估前x 的值。)

(当然这个例子过于简单了,后置条件并没有为人类或计算机添加更多有用的信息。一个更有用的例子在问题的底部..)

所以我可以按如下方式扩展我的toggle 函数,以便在每次调用时检查该条件:

toggle <- function(x){
  old_x <- x
  x <- !x
  assertthat::assert_that(x == !old_x)
  return(x)
}

这当然可行,但我想知道是否有另一种方法可以访问old_x 的值,而无需将其(或结果)明确存储在新名称下。并且无需将后置条件检查代码拆分到函数的顶部和底部。类似于 R 评估函数调用的方式..

我能想到的一种尝试是使用sys.calleval.parent 来访问旧值:

toggle <- function(x){
  x <- !x
  .x <- eval.parent(as.list(sys.call())[[2]])
  assertthat::assert_that(x == !.x)
  return(x)
}

这可行,但我仍然需要分配一个新变量.x,而且[[2]] 的子集还不灵活。然而,像assertthat::assert_that(x == !eval.parent(as.list(sys.call())[[2]]) 这样写是行不通的,并且玩弄sys.call(-1 ..) 的搜索级别也没有帮助。


另一个(更有用的)后置条件添加一些信息的示例:

increment_if_smaller_than_2 <- function(x){
  old_x <- x
  x <- ifelse(x < 2, x <- x + 1, x)
  assertthat::assert_that(all(x >= old_x))
  return(x)
}

有什么提示吗?

【问题讨论】:

    标签: r design-by-contract assertthat


    【解决方案1】:

    您可以通过父环境访问旧的参数值。要使此解决方案起作用,您需要为返回结果引入新变量,即 retval,以防止重新分配给方法参数。恕我直言,这不是一个严重的缺点,因为无论如何都不覆盖方法参数是一种很好的编程风格。您可以即执行以下操作:

    test <- function(.a) {
      retval <- 2 * .a
      assertthat::assert_that(abs(retval) >= abs(.a))
      return(retval)
    }
    
    a <- 42
    test(a)
    # [1] 84
    

    如果您想更进一步并动态提交断言函数,您可以执行以下操作:

    test_with_assertion <- function(.a, assertion) {
      retval <- 2 * .a
      assertthat::assert_that(assertion(retval, eval.parent(.a)))
      return(retval)
    }
    
    a <- 42
    test_with_assertion(a, function(new_value, old_value) 
      abs(new_value) >= abs(eval.parent(old_value)) )
    # [1] 84
    

    这样做,你打算做什么?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-30
      • 1970-01-01
      • 1970-01-01
      • 2015-04-09
      • 1970-01-01
      • 2010-12-02
      • 2011-03-19
      • 2014-03-10
      相关资源
      最近更新 更多