R:退出调用函数

时间:2021-02-14 23:59:19

In R, is there a way to exit from the calling function and return a value? Something like return(), but from the parent function?

在R中,有没有办法退出调用函数并返回一个值?像return(),但来自父函数?

parent <- function(){
  child()
  # stuff afterward should not be executed
} 

child <- function(){
  returnFromParent("a message returned by parent()")
}

It seems stop() is doing something like that. What I want to do is to write a small replacement for stop() that returns the message that stop() writes to stderr.

似乎stop()正在做类似的事情。我想要做的是为stop()写一个小替换,返回stop()写入stderr的消息。

Update after G5W's suggestion: I have a large number of checks, each resulting in a stop() if the test fails, but subsequent conditions cannot be evaluated if earlier checks fail, so the function must exit after a failing one. To do this 'properly', I would have to build up a huge if else construct, which I wanted to avoid.

在G5W的建议之后更新:我有大量的检查,如果测试失败,每个都会导致stop(),但是如果之前的检查失败,则无法评估后续条件,因此该函数必须在失败之后退出。为了'正确',我将不得不建立一个巨大的if else构造,我想避免。

3 个解决方案

#1


5  

Got it. I guess I was looking for something like this:

得到它了。我想我正在寻找这样的东西:

parent <- function(){
  parent_killing_child()
  print("do not run this")
} 

parent_killing_child <- function(){
  do.call(return, list("my message"), envir = sys.frame(-1))
}

parent()

Thanks for all the advices.

感谢您的所有建议。

#2


2  

Disclaimer: This sounds a XY problem, printing the stop message to stdout has few to no value, if interactive it should not be a problem, if in a script just use the usual redirection 2 > &1 to write stderr messages to stdout, or maybe use sink as in answer in this question.

免责声明:这听起来是一个XY问题,打印停止消息到stdout几乎没有价值,如果在交互中它不应该是一个问题,如果在脚本中只是使用通常的重定向2>&1将stderr消息写入stdout,或者在这个问题中使用接收器作为答案。

Now, if I understood properly what you're after I'll do something like the following to avoid too much code refactoring.

现在,如果我正确地理解了你的意思,我将做类似以下的事情,以避免过多的代码重构。

First define a function to handle errors:

首先定义一个处理错误的函数:

my_stop <- function() {
 e <- geterrmessage()
 print(e)
}

Now configure the system to send errors to your function (error handler) and suppress error messages:

现在配置系统以向您的函数发送错误(错误处理程序)并禁止错误消息:

options(error = my_stop)
options(show.error.messages=FALSE)

Now let's test it:

现在让我们测试一下:

f1 <- function() {
  f2()
  print("This should not be seen")
}

f2 <- function() {
  stop("This is a child error message")
}

Output:

> f1()
[1] "Error in f2() : This is a child error message\n"

#3


1  

For the parent function, make a list of tests. Then loop over the tests, and return your message at the first failed test. Subsequent tests will not be executed after the first failure.

对于父函数,请创建一个测试列表。然后遍历测试,并在第一次失败的测试时返回您的消息。第一次失败后,将不会执行后续测试。

Sample code:

test1 <- function(){criteria <- T; return(ifelse(criteria,T,F))} 

test2 <- function(){criteria <- F; return(ifelse(criteria,T,F))} 

test3 <- function(){criteria <- T; return(ifelse(criteria,T,F))} 

parent <- function() {
  tests <- c('test1', 'test2', 'test3')
  for (i in 1:length(tests)) {
    passed <- do.call(tests[i],args = list())
    #print(passed)
    if (!passed){ 
      return(paste("Testing failed on test ", i, ".", sep=''))
    }
  }
  return('Congrats! All tests passed!')
}

parent()

#1


5  

Got it. I guess I was looking for something like this:

得到它了。我想我正在寻找这样的东西:

parent <- function(){
  parent_killing_child()
  print("do not run this")
} 

parent_killing_child <- function(){
  do.call(return, list("my message"), envir = sys.frame(-1))
}

parent()

Thanks for all the advices.

感谢您的所有建议。

#2


2  

Disclaimer: This sounds a XY problem, printing the stop message to stdout has few to no value, if interactive it should not be a problem, if in a script just use the usual redirection 2 > &1 to write stderr messages to stdout, or maybe use sink as in answer in this question.

免责声明:这听起来是一个XY问题,打印停止消息到stdout几乎没有价值,如果在交互中它不应该是一个问题,如果在脚本中只是使用通常的重定向2>&1将stderr消息写入stdout,或者在这个问题中使用接收器作为答案。

Now, if I understood properly what you're after I'll do something like the following to avoid too much code refactoring.

现在,如果我正确地理解了你的意思,我将做类似以下的事情,以避免过多的代码重构。

First define a function to handle errors:

首先定义一个处理错误的函数:

my_stop <- function() {
 e <- geterrmessage()
 print(e)
}

Now configure the system to send errors to your function (error handler) and suppress error messages:

现在配置系统以向您的函数发送错误(错误处理程序)并禁止错误消息:

options(error = my_stop)
options(show.error.messages=FALSE)

Now let's test it:

现在让我们测试一下:

f1 <- function() {
  f2()
  print("This should not be seen")
}

f2 <- function() {
  stop("This is a child error message")
}

Output:

> f1()
[1] "Error in f2() : This is a child error message\n"

#3


1  

For the parent function, make a list of tests. Then loop over the tests, and return your message at the first failed test. Subsequent tests will not be executed after the first failure.

对于父函数,请创建一个测试列表。然后遍历测试,并在第一次失败的测试时返回您的消息。第一次失败后,将不会执行后续测试。

Sample code:

test1 <- function(){criteria <- T; return(ifelse(criteria,T,F))} 

test2 <- function(){criteria <- F; return(ifelse(criteria,T,F))} 

test3 <- function(){criteria <- T; return(ifelse(criteria,T,F))} 

parent <- function() {
  tests <- c('test1', 'test2', 'test3')
  for (i in 1:length(tests)) {
    passed <- do.call(tests[i],args = list())
    #print(passed)
    if (!passed){ 
      return(paste("Testing failed on test ", i, ".", sep=''))
    }
  }
  return('Congrats! All tests passed!')
}

parent()