我完全同情@Dirk 的回答。制作最小包所涉及的少量开销似乎值得遵循“标准方式”。
但是,想到的一件事是source
' 的local
论点,让您可以将源放入一个environment
,您可以像命名空间一样使用它,例如
assign(module, new.env(parent=baseenv()), envir=topenv())
source(filename, local=get(module, topenv()), chdir = TRUE)
要使用简单的语法访问这些导入的环境,请给这些导入环境一个新类(例如,'import'),并使其成为::
泛型,默认为何getExportedValue
时pkg
不存在。
import <- function (module) {
module <- as.character(substitute(module))
# Search path handling omitted for simplicity.
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
了 ,并随后尝试使用 访问其对象之一::
。