繁体   English   中英

将临时命名空间附加到搜索路径

[英]Attaching a temporary namespace to the search path

这个问题是对这篇文章的后续跟进,因为我仍然不完全相信,就代码健壮性而言,输入namespace::foo()习惯而不仅仅是键入foo()并不是更好foo()和祈祷你得到期望的结果;-)

实际问题

我知道这严重违反了“标准R约定”,但我们只是说我很好奇;-) 是否有可能以某种方式将临时命名空间附加到搜索路径?


动机

在我的包mypkg仍然处于“ 开发阶段 ”(即不是真正的R包 )的时候:

  • 我想将我的函数源化为环境mypkg而不是.GlobalEnv
  • 然后将mypkg附加到搜索路径(如果可能的话,作为真正的命名空间)
  • 为了能够调用mypkg::foo()

我完全清楚调用::有它的缺点(它只需要输入一个函数的名称并让R隐式处理查找所需的时间更长)和/或由于a) R扫描搜索路径的方式可能不被认为是必要的和b)包可以导入它们的依赖项(即使用“Imports”而不是“Depends”,而不是导出某些函数等)。 但是我已经看到我的代码至少崩溃了两次,因为某些软件包已经覆盖了某些(基本)函数,所以我从“盲目信任”转变为“更好的安全而不是抱歉”模式; - )

我尝试了什么

AFAIU,命名空间原则上只是一些特殊的环境

> search()
[1] ".GlobalEnv"        "package:stats"     "package:graphics" 
[4] "package:grDevices" "package:utils"     "package:datasets" 
[7] "package:methods"   "Autoloads"         "package:base"     

> asNamespace("base")
<environment: namespace:base>

还有attach()函数将对象附加到搜索路径。 所以这就是我的想法:

temp.namespace <- new.env(parent=emptyenv())
attach(temp.namespace)
> asNamespace("temp.namespace")
Error in loadNamespace(name) : 
  there is no package called 'temp.namespace'

我想我不得不使用attachNamepace()并在library()调用它之前弄清楚它的期望。 有任何想法吗?


编辑

关于Hadley的评论:我实际上并不关心附加环境是一个完全成熟的命名空间还是只是一个普通的环境,只要我可以扩展:: 同时保持“语法sugering”功能 (即能够调用pkg::foo()而不是"::"(pkg="pkg", name="foo")() )。

这就是函数"::"样子:

> get("::")
function (pkg, name) 
{
    pkg <- as.character(substitute(pkg))
    name <- as.character(substitute(name))
    getExportedValue(pkg, name)
}

如果R检测到pkg实际上不是命名空间而只是链接到搜索路径的某个环境,那么它也应该能够做到这一点:

"::*" <- function (pkg, name) 
{
    pkg <- as.character(substitute(pkg))
    name <- as.character(substitute(name))
    paths <- search()
    if (!pkg %in% paths) stop(paste("Invalid namespace environment:", pkg))
    pos <- which(paths == pkg)
    if (length(pos) > 1) stop(paste("Multiple attached envirs:", pkg))
    get(x=name, pos=pos)
}

它有效,但没有语法含糖:

> "::*"(pkg="tempspace", name="foo")
function(x, y) x + y
> "::*"(pkg="tempspace", name="foo")(x=1, y=2)
[1] 3

我怎么能调用pkg::*foo(x=1, y=2) (忽略了::*是一个非常糟糕的函数名称的事实;-))?

你的动机有些不对劲:你的命名空间不必附加到搜索路径以便使用'::'符号,实际上是相反的。

搜索路径允许通过查看附加到搜索路径的所有名称空间来选择符号。

所以,正如Hadley告诉你的那样,你只需要使用devtools :: load_all(),这就是全部...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM