更好地解释什么时候使用Imports / Depends

“ Writing R Extensions ”手册就何时使用Imports或Depends提供了以下指导:

一般规则是

  • 仅使用名称空间来加载使用库(pkgname)的软件包的软件包必须列在“导入”字段中,而不是“取决于”字段中。
  • 需要附加的软件包才能成功地使用库(pkgname)加载软件包,只能列在“取决于”字段中。

有人可以提供更多的唠叨吗? 我怎么知道我的软件包什么时候只需要加载名称空间,什么时候需要连接一个包? 两者的例子是什么? 我认为典型的软件包只是一些函数的集合,有时候在其他软件包中调用函数(其中一些工作已经被编码)。 这是上面的情况1或2吗?

编辑

我写了一篇关于这个特定主题的博文 (search“Imports v Depends”)。 视觉效果使它更容易理解。

"Imports""Depends"更安全(并且使用“取得更好的公民”的包装,相对于其他使用"Depends"包装)。

"Depends"指令试图通过将其他包附加到主要searchpath(即search()返回的环境列表)来确保另一个包中的函数可用。 但是,如果稍后加载的另一个程序包在searchpath的前面放置了一个名称相同的函数,则可以阻止此策略。 Chambers( 在SoDA中 )使用gammgcv包中的函数"gam"的示例。 如果加载了两个其他包,其中一个取决于gam ,另一个取决于mgcv ,调用gam()所发现的函数将取决于这两个包所附加的顺序。 不好。

"Imports"指令将导入的包放在<imports:packageName> (紧接在<namespace:packageName>后面search),而不是常规searchpath中。 如果上面例子中的任何一个包使用"Imports"机制,则可以通过两种方式来改善问题。 (1)程序包本身可以控制使用哪个mgcv函数。 (2)通过保持导入对象的主要searchpath清晰,甚至不会打破其他mgcv函数对其他包的依赖。

这就是为什么使用命名空间是一个很好的做法,现在为什么现在由CRAN强制执行,特别是为什么使用"Imports"比使用"Depends"更安全。


编辑添加一个重要的警告:

一个不幸的例外是上面的build议:如果你的软件包依赖于一个自己"Depends"于另一个软件包B "Depends"软件包B ,你的软件包可能需要附加一个"Depends指令”。

这是因为程序包A中的函数编写时期望程序包B及其函数将被附加到search()path

"Depends"指令将加载和附加包A ,此时包A自己的"Depends"指令将在连锁反应中导致包B被加载和附着。 包A的函数将能够find它们所依赖的包B的函数。

"Imports"指令将加载但附加包A既不加载也不附加包B (毕竟, "Imports"期望包编写者使用名称空间机制,而包A将使用"Imports"指向B中需要访问的任何函数。)通过函数调用依赖于包Bfunction的包B将因此失败。

唯一的两个解决scheme是:

  1. 使用"Depends"指令让您的软件包附加软件包A
  2. 更好的是,长远来看,请联系A包的维护者,并要求他们在构build他们的名字空间方面做更细致的工作(用马丁·摩根的话来说, 这个相关的答案 )。

哈德利·韦翰(Hadley Wickham)给出了一个简单的解释( http://r-pkgs.had.co.nz/namespace.html ):

在“ Depends或“ Imports列出软件包可确保在需要时安装软件包。 主要区别在于,在Imports只加载包的情况下, Depends附加它。 没有其他的区别。 […]

否则,除非有充分的理由,否则应始终在“不Depends Imports列出软件包。 这是因为良好的软件包是独立的,并且可以最大限度地减less全球环境(包括searchpath)的变化。 唯一的例外是,如果你的包被devise成与另一个包一起使用。 例如,模拟包装build立在素食主义者之上。 如果没有素食主义者,它是没有用的,所以它的素食主义Depends Imports 。 同样,ggplot2应该真的取决于比例尺,而不是导入它。

SfDA分会说,当这个软件包使用“命名空间”机制时,使用“Imports”,并且现在要求所有的软件包都具有它们,那么现在答案可能总是使用“Imports”。 在过去的包可能已经加载没有实际有名称空间,在这种情况下,你将需要使用取决于。