【问题标题】:Global variable in a package - which approach is more recommended?包中的全局变量 - 更推荐哪种方法?
【发布时间】:2015-01-31 00:49:31
【问题描述】:

我明白全局变量通常是邪恶的,我应该避免它们,但是如果我的包确实需要一个全局变量,这两种方法中哪一种更好?还有其他推荐的方法吗?

  1. 使用对包可见的环境

    pkgEnv <- new.env()  
    pkgEnv$sessionId <- "xyz123"
    
  2. 使用options

    options("pkgEnv.sessionId" = "xyz123")
    

我知道还有一些其他线程询问如何实现全局变量,但我没有看到关于推荐哪个的讨论

【问题讨论】:

    标签: r packages


    【解决方案1】:

    一些包使用隐藏变量(以. 开头的变量),例如.Random.seed.Last.value 在base R 中使用。在你的包中你可以这样做

    e <- new.env()
    assign(".sessionId", "xyz123", envir = e)
    ls(e)
    # character(0)
    ls(e, all = TRUE)
    # [1] ".sessionId"
    

    但是在你的包中你不需要指定e。您可以使用.onLoad() 挂钩在加载包时分配变量。

    .onLoad <- function(libname, pkgname) {
        assign(".sessionId", "xyz123", envir = parent.env(environment()))
    }
    

    请参阅 this question 及其答案,了解有关包变量的一些很好的解释。

    【讨论】:

    • 一些 cmets 通过您的链接建议您使用 e &lt;- new.env(parent=emptyenv()) 的第一种方法是最好的方法。但这似乎与您设置envir = parent.env(environment()) 的第二种方法不一致?我都试过了。两者都有效。但这东西在我头上。这两种方法是否基本相同,或者我是否更有可能在使用其中一种方法时遇到挑剔的行为?
    【解决方案2】:

    当大多数人说您应该避免使用“全局”变量时,他们的意思是您不应该分配给全局环境(.GlobalEnvGlobalEnvas.environment(1)),或者您不应该通过以下方式在内部函数之间传递信息除了将此类数据作为函数调用的参数传递之外的任何方法。

    缓存完全是另一回事。我经常缓存我不想重新计算(记忆)或重新查询的结果。我在包中经常使用的一种模式如下:

    myFunction <- local({
    
        cache <- list() # or numeric(0) or whatever
    
        function(x,y,z){ 
    
            # calculate the index of the answer 
            # (most of the time this is a trivial calculation, often the identity function)
            indx = answerIndex(x,y,z)
    
            # check if the answer is stored in the cache
            if(indx %in% names(cacheList))
                # if so, return the answer
                return(cacheList[indx])
    
            [otherwise, do lots of calculations or data queries]
    
            # store the answer
            cahceList[indx] <<- answer
    
            return(answer)
        }
    
    })
    

    local 的调用创建了一个新环境,我可以在其中使用范围赋值运算符&lt;&lt;- 存储结果,而不必担心包已经密封,最后一个表达式(函数定义)是作为对local() 的调用的值返回并绑定到名称myFunction

    【讨论】:

      猜你喜欢
      • 2016-01-02
      • 1970-01-01
      • 2010-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-12
      • 1970-01-01
      相关资源
      最近更新 更多