在函数结束前通过eval fires进行on.exit调用

在函数结束前通过eval fires进行on.exit调用,r,R,知道eval实现为什么在函数结束之前触发回调吗 # on.exit fires on exit exit_test1 = function(){ on.exit(expr = message('close')) message('hello') } exit_test1() #> hello #> close # on.exit fires before exit exit_test2 = function(){ eval(parse(text = "on.e

知道eval实现为什么在函数结束之前触发回调吗

# on.exit fires on exit
exit_test1 = function(){
  on.exit(expr = message('close'))
  message('hello')
}
exit_test1()
#> hello
#> close

# on.exit fires before exit
exit_test2 = function(){
  eval(parse(text = "on.exit(expr = message('close'))"))
  message('hello')
}
exit_test2()
#> close
#> hello

在的文档中提到了这一点
eval
不会在正确的帧环境中对.exit()上的
进行求值

exit_test2 = function() {
  exit_cmd = quote(on.exit(expr = message('close 2')))
  message('hello')
  rlang::eval_bare(exit_cmd)
  message('hello')
}
exit_test2()
#> hello
#> hello
#> close 2

除了@Paul的解决方案,事实上我需要执行一个字符串,所以这就是解决方案:

exit_test2 = function() {
  exit_cmd = quote(on.exit(expr = eval(parse(text="message('close')"))))
  rlang::eval_bare(exit_cmd)
  message('hello')
}
exit_test2()
#> hello
#> close

on.exit
将内容添加到错误的帧堆栈中。为什么要在
打开的情况下使用
eval
。退出
?我正在探索跟踪复杂的算法流程,这意味着在函数结束时记录日志。Eval将使我能够使用基于R6的OOP方法对日志进行模块化。我知道这并不重要,但这意味着我可以将日志代码减少到每个函数中的一个调用,而不是使用大量分布式代码。