r - 有条件地修改父函数的行为

标签 r function namespaces call evaluation

背景

我有兴趣将对象返回到函数的父框架并停止执行父函数而没有错误。

笔记

我经历了一些讨论 on related questions并同意更广泛的观点,即这不一定是最佳实践。我最感兴趣的是出于教育目的而这样做,并更好地了解如何使用 function call stack .

可重现的例子
check_conditions
此函数应检查条件,并在某些特定情况下将结果返回给父函数。

check_conditions <- function(x) {
    stopifnot(is.numeric(x),
              x %% 1 == 0)
    # And for x == 9 always return 9
    if (x == 9) {
        eval.parent(return(1))
        stop()
    }
}

其他功能

其余函数使用 check_conditions功能并稍后做自己的事情(或不,如果停止)。
fun_a <- function(x) {
    check_conditions(x)
    x^2
}

fun_b <- function(x) {
    check_conditions(x)
    x+1
}

问题
>> fun_b(1)
[1] 2

>> fun_a(9)
[1] 81

>> fun_b(9)
[1] 10

在上面的例子中,我想要 fun_afun_b返回值 1 ,根据条件:
if (x == 9) {
            eval.parent(return(1))
            stop()
        }

笔记
  • 我不想返回错误消息。那里应该是没有消息表示剩余的调用跨越 fun_afun_b没有被处理。

  • 更新(根据评论)
  • 我不想改变fun_a的正文或 fun_b , check_conditions可以改变。
  • 应该可以改变假设 fun_n 的行为这也引用了 check_conditions无需编辑该功能。 check_conditions应该能够返回和停止(没有错误或警告)并在函数的父环境中返回值,R-ish 伪代码
    check_conditions <- function(x) {
    if (x == 9) {
       call(env = parent.frame(),
            expr = {
                    return(1)
                    # Do not execute anything else from 
                    # the parent environment.
            }
      }
     }
    
  • 最佳答案

    这是从旧答案修订的。它不需要check_conditionsfun_a被改变,但确实要求:

  • fun_a通过电话注册,例如fun_a <- validity_check(fun_a)之后fun_a可以用
  • 调用 check_conditions必须是正文的第一行
  • check_conditions 采用与 fun_a 相同的参数

  • 代码:
    validity_check <- function(fun) {
       cl <- body(fun)[[2]][[1]]
       function(...) {
         mc <- match.call()
         mc[[1]] <- cl
         check_val <- eval.parent(mc)
         if (!is.null(check_val)) check_val
         else fun(...) 
       }
    }
    
    # test - fun_a and check_conditions as in question
    
    fun_a <- validity_check(fun_a)
    
    fun_a(9)
    ## [1] 1
    
    fun_a(2)
    ## [1] 4
    

    较旧的答案 我不清楚哪些可以更改,哪些不能更改,但是如果我们可以修改所有功能,那么:
    check_conditions <- function(x) {
        stopifnot(is.numeric(x), x %% 1 == 0)
        if (x == 9) structure(1, class = "bad")
    }
    
    fun_a <- function(x) {
      cc <- check_conditions(x)
      if (inherits(cc, "bad")) unclass(cc) else x^2
    }
    
    fun_a(9)
    ## [1] 1
    
    fun_a(2)
    ## [1] 4
    

    关于r - 有条件地修改父函数的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46132347/

    相关文章:

    r - 如何使用目标向量根据元素对列表进行排序?

    r - 在 R 中调用 "install.packages()"时从 Github 安装一些部件

    Javascript函数说没有声明?

    Javascript/Jquery 在浏览器宽度变化时运行函数?

    r - 在没有 "rownumber"(和书签)的情况下将 data.frame 从 R 转置到 Latex

    c - 跳出这个 while 循环

    python - 雅虎体育 API XML 命名空间找不到元素

    xml - 加载不包含命名空间的 XML

    c++ - 为什么我必须在包含 <iostream> 后编写 std::cin ?

    r - 写入从 SparkR:::map 返回的 R 数据帧