【问题标题】:reg.finalizer() in an R package does not execute at the end of an R sessionR 包中的 reg.finalizer() 不会在 R 会话结束时执行
【发布时间】:2018-01-23 16:31:45
【问题描述】:

来自 R 中的文档 ?reg.finalizer

除其他外,它提供了一种在 R 会话结束时对代码进行编程的方法,无需操纵 .Last。对于在包中使用,在命名空间中的对象上设置终结器通常是一个好主意:然后它将在会话结束时调用,或者如果在会话期间完成命名空间卸载后不久就会调用它。

似乎我可以在 R 会话结束时使用reg.finalizer() 运行某些代码,但它对我不起作用。我在https://github.com/yihui/finalizer-test准备了一个最小的包,基本包含以下代码:

e = new.env()

reg.finalizer(e, function(e) {
  message('Bye!')
}, onexit = TRUE)

如果我只是在交互式 R 会话中运行上述代码并退出会话,我可以看到消息 Bye!,但如果我安装上述包(您可以使用 devtools::install_github('yihui/finalizer-test')),请将其加载到 R会话,并退出 R 会话,我没有看到该消息。我想知道为什么在这种情况下不执行终结器。

FWIW,当我安装包时,我可以看到消息Bye!

$ R CMD INSTALL .

* installing to library ‘/Users/yihui/R’
* installing *source* package ‘finalizer’ ...
** R
** preparing package for lazy loading
No man pages found in package  ‘finalizer’ 
** help
*** installing help indices
Bye!
** building package indices
** testing if installed package can be loaded
* DONE (finalizer)

当我运行以下命令时,我也没有看到该消息:

$ R -e "library(finalizer)"
> library(finalizer)
> 
> 
$ 

【问题讨论】:

    标签: r finalizer r-package


    【解决方案1】:

    如果您将终结器函数注册到包名称空间环境,它就会起作用。您可以为此使用.onLoad 钩子:

    e = new.env()
    
    reg.finalizer(e, function(e) {
      message('Object Bye!')
    }, onexit = TRUE)
    
    
    finalize <- function(env) {
       print(ls(env))
       message("Bye from Name space Finalizer")
    }
    
    
    .onLoad <- function(libname, pkgname) {
       parent <- parent.env(environment())
       print(str(parent))
       reg.finalizer(parent, finalize, onexit= TRUE)
    }
    

    对象终结器函数未被调用,但由于您拥有整个命名空间环境,您可能不需要它。

    我在https://github.com/mpbastos/finalizer-test 上创建了你的测试包的一个分支:

    > devtools::install_git("https://github.com/mpbastos/finalizer-test")
    Downloading git repo https://github.com/mpbastos/finalizer-test
    Installing finalizer
    "C:/PROGRA~1/R/R-34~1.0/bin/x64/R" --no-site-file --no-environ --no-save  \
      --no-restore --quiet CMD INSTALL  \
      "C:/Users/mbastos/AppData/Local/Temp/RtmpOGymjQ/file5cf829e63957"  \
      --library="\\sharedfs/MyDocs6/mbastos/Documents/R/win-library/3.4"  \
      --install-tests
    
    * installing *source* package 'finalizer' ...
    ** R
    ** preparing package for lazy loading
    ** help
    No man pages found in package  'finalizer'
    *** installing help indices
    ** building package indices
    Object Bye!
    ** testing if installed package can be loaded
    *** arch - i386
    <environment: namespace:finalizer>
    NULL
    [1] "e"        "finalize"
    Bye from Name space Finalizer
    *** arch - x64
    <environment: namespace:finalizer>
    NULL
    [1] "e"        "finalize"
    Bye from Name space Finalizer
    * DONE (finalizer)
    > library(finalizer)
    <environment: namespace:finalizer>
    NULL
    > q()
    Save workspace image? [y/n/c]: n
    [1] "e"        "finalize"
    Bye from Name space Finalizer
    

    【讨论】:

      【解决方案2】:

      不是一个真正的答案(接受的答案很好),但我也注意到在某些情况下,当终结器在退出时运行时,像 print 和 cat 这样的函数不会产生可见的输出,至少在使用 RStudio 时是这样。

      我还没有看到模式,但我猜有一个竞速条件,并且在某些情况下 stdout 在终结器函数执行/完成之前关闭。我猜同样的问题可以用 message() 来解决

      因此,如果您想在退出时执行它,使用消息测试函数可能会误导您。

      【讨论】:

        猜你喜欢
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-10
        • 1970-01-01
        • 2019-05-24
        • 2014-11-29
        相关资源
        最近更新 更多