我完全同意@Dirk的回答。制作最小包时涉及的小额开销似乎值得遵循“标准方式”。
然而,我想到的一件事是
source
的
local
参数,它可以让你将代码源引入一个
environment
中,就像使用命名空间一样,例如:
assign(module, new.env(parent=baseenv()), envir=topenv())
source(filename, local=get(module, topenv()), chdir = TRUE)
为了用简单的语法访问导入的环境,请给这些导入环境分配一个新类(比如“import”),并将
::
指定为通用设置,当
pkg
不存在时,默认使用
getExportedValue
。
import <- function (module) {
module <- as.character(substitute(module))
filename <- paste(module, 'R', sep = '.')
e <- new.env(parent=baseenv())
class(e) <- 'import'
assign(module, e, envir=topenv())
source(filename, local=get(module, topenv()), chdir = TRUE)
}
'::.import' <- function(env, obj) get(as.character(substitute(obj)), env)
'::' <- function(pkg, name) {
pkg <- as.character(substitute(pkg))
name <- as.character(substitute(name))
if (exists(pkg)) UseMethod('::')
else getExportedValue(pkg, name)
}
更新
以下是一个更安全的选项,可以避免在加载的包中包含与使用::
访问的包具有相同名称的对象时出现错误。
'::' <- function(pkg, name) {
pkg.chr <- as.character(substitute(pkg))
name.chr <- as.character(substitute(name))
if (exists(pkg.chr)) {
if (class(pkg) == 'import')
return(get(name.chr, pkg))
}
getExportedValue(pkg.chr, name.chr)
}
假设你加载了
data.table
,随后尝试使用
::
访问其中一个对象,则可以得到正确的结果。
?sys.source
示例中所示)是不够的吗? - Joshua Ulrichget
和assign
来实现相同的功能,但是::
的语法更加优美一些。 - Konrad Rudolphimport
函数并没有这样做。如果你将每个文件的内容放在搜索路径上的单独环境中,你可以使用$
运算符访问特定的环境(例如strings$concatenate()
)。 - Joshua Ulrich