又名玩火...
以下不起作用:
rstd.obj <- as.environment("tools:rstudio")
detach("tools:rstudio")
attach(rstd.obj, name="tools:rstudio")
好吧,它似乎有效,但随后各种奇怪的错误开始出现。问题是非常烦人(尽管我确信有一个很好的理由)attach
制作环境的副本并附加它,而不是直接附加环境:
rstd.obj
# <environment: 0x000000000930edd0>
# attr(,"name")
# [1] "tools:rstudio"
as.environment("tools:rstudio")
# <environment: 0x000000000a21b4c8>
# attr(,"name")
# [1] "tools:rstudio"
请注意环境实际上有何不同(如果您查看源代码也可以确认这一点)do_attach
in src/main/envir.c@2124(R3.0.2)
副本的制作地点)。
然而,这完全可以正常工作(重新启动 RStudio 以重置所有内容后):
rstd.obj <- as.environment("tools:rstudio")
rstd.parent <- as.environment("package:stats") # this was #3 on search path for me
detach("tools:rstudio")
# WARNING: YOU'RE PLAYING WITH FIRE IF YOU RUN THIS, DO
# SO AT YOUR OWN RISK:
parent.env(.GlobalEnv) <- rstd.obj
parent.env(rstd.obj) <- rstd.parent
而不是使用detach
/attach
, 我们刚刚detach
,并使用强行将对象插入回搜索路径parent.env<-
。另一方面,我猜这样做可能接近 R Core 在警告时的想法?parent.env
:
替换功能parent.env<-
极其危险,因为它可用于以违反内部 C 代码所做假设的方式破坏性地改变环境。它可能会在不久的将来被删除。
解决此问题的另一种方法是使用detach
/attach
,然后循环遍历中的所有函数tools:rstudio
搜索路径上的环境并将其环境重置为搜索路径上原始环境的副本(顺便说一句,这就是 Rstudio 开始崩溃的原因:函数环境仍然是从搜索路径中删除的对象,但该环境不在不再是搜索路径,只是它的副本)。但这感觉非常hacky。
另外,如果有人知道有关“内部 C 代码所做的假设”的更多详细信息,我将非常有兴趣听到它们。显然,我们可以在搜索路径中引入循环(不,我不是不小心搞乱了这些例子......),但是还有其他问题吗?
编辑:关于上述内容,来自的超级有用的花絮R-devel http://r.789695.n4.nabble.com/Making-parent-env-lt-an-error-for-package-namespaces-and-package-imports-td4698432.html:
我想提议对 R 语言进行更改,以便调用
包命名空间或包导入上的“parent.env
卢克·蒂尔尼的回答是:
我会调查一下
这似乎证实了人们的担忧是以 R 可能无法跟踪的方式更改调用或搜索路径中的调用堆栈,这与通常的想法相反parent.env<-
对于其他环境链来说是危险的(清楚地阅读这里的行间)。