"Imports"
比"Depends"
(比使用其他包装更安全)(并且使使用它的包装成为“更好的公民” "Depends"
)。
甲"Depends"
指令的尝试,以确保从另一程序包的功能是可用的由其它包附加到主搜索路径(即,由返回的环境的列表search()
)。但是,如果稍后加载的另一个程序包在搜索路径上更早放置了一个名称相同的函数,则可以阻止此策略。Chambers(在SoDA中)使用函数的示例,"gam"
可以在gam
和mgcv
包中找到该函数。如果加载了另外两个软件包,则其中一个依赖于gam
,一个依赖于mgcv
,调用所找到的功能gam()
将取决于这两个软件包的连接顺序。不好。
一个"Imports"
指令应该用于任何支持包,其功能将被放置在<imports:packageName>
(后立即搜索<namespace:packageName>
),而不是常规的搜索路径。如果以上示例中的任何一个软件包都使用了该"Imports"
机制(在文件中也需要import
或importFrom
指令NAMESPACE
),则可以通过两种方式来改善问题。(1)程序包本身将获得对使用哪个mgcv
功能的控制。(2)通过使主搜索路径远离导入的对象,它甚至不会潜在地破坏另一个程序包对另一个mgcv
函数的依赖性。
这就是为什么使用名称空间是一个好习惯的原因,为什么它现在由CRAN强制执行,并且(尤其是)为什么使用using "Imports"
比使用using 更安全"Depends"
。
编辑添加了一个重要的警告:
有一个不幸的是常见的例外上面的建议:如果你的包依赖于一个封装A
本身"Depends"
上的另一个包B
,你的包可能需要附加A
一个"Depends
指令。
这是因为程序包A
中的函数是在编写程序包时期望程序包B
及其功能将附加到search()
路径上的。
甲"Depends"
指令将加载和附着封装A
,在该点包A
自身的"Depends"
指令将在链反应,导致包B
被装载和连接的为好。A
然后,包中的功能将能够找到B
它们所依赖的包中的功能。
一个"Imports"
指令将加载,但不重视包装A
和意志没有负载,也没有附加包B
。("Imports"
毕竟,期望程序包编写者正在使用名称空间机制,并且该程序包A
将"Imports"
用于指向B
需要访问的任何函数。)函数调用A
依赖于程序包中函数的程序包中的任何函数B
将因此失败。
仅有的两种解决方案是:
A
使用"Depends"
指令使程序包附加程序包。
- 从长远来看,更好的方法是,与软件包的维护者联系,
A
并要求他们在构造其命名空间时做得更加认真(用这个相关答案中的Martin Morgan来说)。