Push return to parent function

丶灬走出姿态 提交于 2019-12-13 07:08:11

问题


Is there a way how to force parent function to return an output? Say I have a function that 'does something' and at the beginning of each function a want to 'check something'. If the check fails I want to return 'something else'.

In my example below 'does something' is logarithm, 'check something' means checking that the variable is nonnegative and 'something else' is minus infinity.

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

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

This example doesn't work

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

One solution is to return 'something else' from the check function if the checks find a problem and NULL otherwise. Then I can write one if in the parent function and it's done.

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

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

This solution still keeps most of the functionality in separated function check() but is there a way to have all the functionality in it?


In the real problem the checking function does more than just one comparison and it is used in multiple functions so it is necessary to have it separately. Also 'something else' that returns the check function depends on condition which the input fails.


More realistic example:

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

回答1:


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

More common is the use case where you want to throw an error when check fails:

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


来源:https://stackoverflow.com/questions/42858804/push-return-to-parent-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!