【问题标题】:How to attach a function to my package's namespace after it's loaded?加载后如何将函数附加到我的包的命名空间?
【发布时间】:2015-04-25 02:49:58
【问题描述】:

这似乎是一个奇怪的问题,但我确实有一个我正在尝试弄清楚的用例。

假设我正在编写一个包,并且我有一个函数,我想允许用户使用其他名称 - 用户提供函数的名称。我想知道实现这一目标的最佳方法是什么?

#' @export
foo <- function() "Hello"
#' @export
addAlias <- function(x) assign(x, foo, envir = globalenv())

这是我想要得到的行为——现在用户可以调用addAlias("bar"),然后如果他调用bar(),就好像他调用了我的函数。

显然这不是一个好的解决方案,因为它分配给全局环境。有没有人对什么是最好的方法有反馈?我尝试了几种方法:

1.分配给 globalenv

就像我在示例中展示的那样。这似乎奏效了。

2。分配给包的环境

addAlias <- function(x) assign(x, foo, as.environment("package:mypackage"))

这工作了一段时间,直到我意识到它只适用于 devtools 而不是由于锁定环境而正确加载包时

3.将新环境附加到搜索路径

.onLoad <- function(libname, pkgname) {
  assign("aliases", new.env(), envir = parent.env(environment()))
  attach(aliases)
  invisible()
}

addAlias <- function(x) assign(x, foo, aliases)

我不喜欢这个,因为使用了attach。在这种情况下是否有保证?我什么时候detach

4.公开一个单独的命名环境

#' @export
#' @keywords internal
aliases <- new.env()

addAlias <- function(x) assign(x, foo, aliases)

这可行,但用户不能调用bar(),而是需要调用alises$bar()mypackage::aliases$bar()。我不喜欢那样,但这是一个有趣的实验。也不知道这样导出变量行不行?

感谢任何帮助

【问题讨论】:

    标签: r r-package


    【解决方案1】:

    我认为更合适的方式是使用closure

    #' @export
    foo <- function() "Hello"
    #' @export
    getfoo <- function() {
        function(){
            # do anything, including running foo()
            foo()
        }
    }
    

    有了这个,你就可以了

    > bar <- getfoo()
    > bar()
    [1] "Hello"
    

    【讨论】:

    • 感谢您的提示。但我不认为这回答了主要问题?
    • 我认为这是实现您想做的替代解决方案。我认为将变量分配给锁定的环境并不是实现此目的的有效方法。
    • 所以为了确保我理解 - 使用这种方法,您是在建议用户对变量进行赋值,而不是在代码中进行赋值,对吗?我希望用户传入一个字符串向量并将它们中的每一个分配给我的函数。我不明白如何用这段代码做到这一点?
    • 你可以让用户选择他们想要获得多少个实例吗?例如,可以bars &lt;- replicate(100, getfoo()); bars[[1]]()
    • 不,这对我的需要不起作用 :) 我需要让用户调用一个带有字符串向量的函数,并且在函数内部它会创建与用户可以调用的那些字符串的绑定之后。但这不是返回值,我返回的是别的东西。
    猜你喜欢
    • 2019-12-28
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-29
    相关资源
    最近更新 更多