2017-03-17 68 views
0

有没有办法如何强制父功能返回输出?假设我有一个“做某些事情”的功能,并且在每个功能开始时想要“检查某些事情”。如果检查失败,我想返回'别的东西'。推返回父功能

在我的例子中,'有些事情'是对数,'检查某事'是指检查变量是非负的,'其他'是负无穷大。

weird_log <- function(x) { 
    check(x) 
    log(x) 
} 

check <- function(x) { 
    if (x <= 0) 
    eval.parent(parse(text = 'return(-Inf)')) 
} 

这个例子不起作用

weird_log(10) # 2.302585 
weird_log(-10) # NaN 

一种解决方案是从检查函数返回“别的东西”。如果检查发现的问题和NULL否则。然后我可以在父函数中写一个if并完成。

weird_log <- function(x) { 
    y <- check(x) 
    if (!is.null(y)) return(y) 
    log(x) 
} 

check <- function(x) { 
    if (x <= 0) { 
    -Inf 
    } else { 
    NULL 
    } 
} 

这个解决方案仍然保持大部分的功能分离check()的功能,但有没有办法在它所有的功能?


在真正的问题中,检查函数做的不仅仅是一个比较,它被用在多个函数中,所以有必要单独使用它。另外返回check函数的“别的东西”取决于输入失败的条件。


更现实的例子:

weird_log <- function(input) { 
    y <- check(input) 
    if (!is.null(y)) return(y) 
    list(log = log(input$x)) 
} 

check <- function(input) { 
    if (is.null(input$x)) { 
    list(error = 'x is missing') 
    } else if (!is.numeric(input$x)) { 
    list(error = 'x is not numeric') 
    } else if (x <= 0) { 
    list(log = -Inf, warn = 'x is not positive') 
    } else { 
    NULL 
    } 
} 
+0

为什么你甚至需要'parse(text = 'return(-Inf)')'在那里。不会''eval.parent(return(-Inf))'做同样的事情吗?我不知道你们在哪里学习,但这是非常糟糕的代码练习。 –

+0

好点,我已经过分复杂了。 –

回答

4

KISS

weird_log <- function(x) { 
    if (check(x)) return(-Inf) 
    log(x) 
} 

check <- function(x) { 
    x <= 0 
} 

weird_log(10) # 2.302585 
weird_log(-10) # -Inf 

更常见的是,你要当检查失败引发错误的用例:

weird_log <- function(x) { 
    check(x) 
    log(x) 
} 

check <- function(x) { 
    if(x <= 0) stop("x <= 0", call. = FALSE) 
} 

weird_log(10) # 2.302585 
weird_log(-10) # Error: x <= 0 
+0

我没有指定,但检查的输出可能会有所不同,这取决于内部的几个条件。所以检查不能简单地返回'TRUE' /'FALSE'。我也不能使用stop(),错误对于这个问题是不可接受的。 –

+0

这并没有改变我的观点。返回语句应始终是您想要返回的函数的一部分。检查可能会返回一个整数值,并且可以在父函数中使用开关。 – Roland