R 包/命名空间环境中相同命名函数的值/引用相等性?

R 包/命名空间环境中相同命名函数的值/引用相等性?,r,R,让我们抓取环境“namespace:stats”和“package:stats” 现在,让我们以两种方式获取函数“sd”: 它们是一样的吗?他们是!但“相同”是什么意思?参考还是价值平等 identical( nsSd , pkgSd ) 这意味着引用相等,因为以下返回FALSE: test1 = function() {} test2 = function() {} identical( test1 , test2 ) 但如果这是真的,则意味着环境的框架可以在函数对象旁边包含函数指针。使问

让我们抓取环境“namespace:stats”和“package:stats”

现在,让我们以两种方式获取函数“sd”:

它们是一样的吗?他们是!但“相同”是什么意思?参考还是价值平等

identical( nsSd , pkgSd )
这意味着引用相等,因为以下返回FALSE:

test1 = function() {}
test2 = function() {}
identical( test1 , test2 )
但如果这是真的,则意味着环境的框架可以在函数对象旁边包含函数指针。使问题进一步复杂化的是,函数可以“生存”在一个环境中,但可以告诉函数其执行环境是另一个环境。钱伯斯苏打水似乎没有答案(这是一本厚厚的书,也许我错过了!)

所以,我想要一个明确的答案。以下哪项是正确的?还是这里有假三分法

  • nsSd
    pkgSd
    是两个不同的对象(尽管是各自的副本) 其他),其中
    pkgSd
    中的对象将
    ns
    作为其执行对象 环境
  • nsSd
    pkgSd
    是指向同一对象的指针
  • nsSd
    是指向
    pkgSd
    的指针,因此它们被视为相同

  • 这并不是你主要问题的答案。不过,在这个问题上,我同意Dirk的观点:只有一个
    sd()
    函数,根据具体情况,可以通过不同的作用路径访问它。例如,当您在命令行中键入
    sd(x)
    时,将通过
    package:stats
    环境框架中的条目找到与名称
    sd
    对应的函数。当您键入
    stats:::sd(x)
    时,或者当
    stats
    包中的另一个函数调用
    sd(x)
    时,将通过在
    命名空间:stats
    环境中搜索找到它


    相反,我只想指出,您使用
    test1()
    test2()
    的示例实际上并不意味着计算结果与
    相同的对象的“引用相等”。要想了解这两个属性不完全相同的真正原因,请查看
    str()
    所揭示的它们的结构:


    它们是指向同一对象的指针。使用它,我们可以检查两个对象是否引用了内存中的同一个位置

    are_same <- function(x, y)
    {
      f <- function(x) capture.output(.Internal(inspect(x)))
      all(f(x) == f(y))
    }
    
    are_same(nsSd, pkgSd) #TRUE
    are_same(1:5, 1:5)    #FALSE
    

    are\u same可能值得一看内部
    idential
    函数的c代码。我觉得你把生活搞得太复杂了。我们知道只有一个
    sd()。匹配指针视为相同,否则它将检查相同的
    形式
    正文
    以及任何
    CLOENV(x)
    的内容。第二个示例在检查正文时失败<代码>相同(正文(test1),正文(test2))
    FALSE
    .Dirk-您能详细说明一下吗?我不知道只有一个sd(),这就是为什么我发布=)看起来您在区分环境和名称空间,您是指包环境和名称空间环境吗?我想你是说答案是2或3以上?谢谢,乔希!这是一篇很有见地的文章。我觉得Chambers调用re:sourcefile attribute=)@SFun28-很高兴在这里看到你。回复:钱伯斯的苏打,“浓密”是对这本书的一个很好的描述;让我惊讶的是,里面没有浪费一页。它确实回报了你为阅读它所付出的一切努力,我对此表示感谢。干杯。同意了……里面塞满了好东西。这篇文章代表了我在写一篇关于R如何搜索和查找东西的博客文章时的“缺失链接”。这是我从过去的帖子、钱伯斯和其他来源收集的发现,并试图做比
    search()
    更深的工作。我不认为任何一个来源都能用易于理解的视觉效果清楚地解释这个过程。在我发布之前,我想先给你发一份评论稿。谢谢,乔希!我已经把你的电子邮件抄下来了。很抱歉回复得太晚,我不得不为情人节的事逃之夭夭=)我希望你仍然可以删除评论,如果没有的话,我很抱歉。我可能会在未来两三周内寄给你一份草稿。@SFun28太好了。评论被删除了,我期待着在你有机会完成后看到草稿。我开始了一项悬赏,我将奖励你,以表达我对你的感谢(当24个等待期到期时),你非常慷慨。很高兴我能帮上忙。很酷的功能。直到现在,我还不知道当我做
    j@JoshO'Brien:是的,尽管R假装总是按值传递东西,但为了获得更好的性能,它确实会在可以逃脱的时候偷偷地传递对对象的引用。这是不是通过承诺实现的,就像实现函数参数的惰性计算一样?
    
    test1 = function() {}
    test2 = function() {}
    identical( test1 , test2 )
    
    test1 <- function() {}
    test2 <- function() {}
    identical( test1 , test2 )
    # [1] FALSE
    
    str(test1)
    # function ()  
    #  - attr(*, "srcref")=Class 'srcref'  atomic [1:8] 1 13 1 25 13 25 1 1
    #   .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x01613f54> 
    
    str(test2)
    # function ()  
    #  - attr(*, "srcref")=Class 'srcref'  atomic [1:8] 1 13 1 25 13 25 1 1
    #   .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x01615730> 
    
    options(keep.source=FALSE)
    test1 <- function() {}
    test2 <- function() {}
    identical( test1 , test2 )
    # [1] TRUE
    
    are_same <- function(x, y)
    {
      f <- function(x) capture.output(.Internal(inspect(x)))
      all(f(x) == f(y))
    }
    
    are_same(nsSd, pkgSd) #TRUE
    are_same(1:5, 1:5)    #FALSE