如何在R包中使用get0仅在包名称空间内搜索?
假设我的包中有一个内部函数,称之为如何在R包中使用get0仅在包名称空间内搜索?,r,namespaces,package,arguments,R,Namespaces,Package,Arguments,假设我的包中有一个内部函数,称之为is(),如果is(),则可以认为它是一个更通用的版本。特别是,它搜索专门的函数,这些函数用于判断提供的对象是否是给定的类。例如,is u()可以编程为: is_ <- function(obj, class) { if (exists(paste0("is.", class))) { get0(paste0("is.", class))(obj) } else inherits(obj, cl
is()
,如果is()
,则可以认为它是一个更通用的版本。特别是,它搜索专门的函数,这些函数用于判断提供的对象是否是给定的类。例如,is u()可以编程为:
is_ <- function(obj, class) {
if (exists(paste0("is.", class))) {
get0(paste0("is.", class))(obj)
}
else inherits(obj, class)
}
在我定义的地方
is.numeric_vector <- function(x) is.numeric(x) && is.null(dim(x))
is.numeric\u vector问题在于包名称空间将从从全局环境继承的基本名称空间继承。有关更详细的说明,请参见此处:。如果您想对符号查找进行更多控制,则需要自己完成这项工作。您可以在包中包含自己的get
函数
# These are private helpers that do not need to be exported from your package.
.pkgenv <- environment()
get1 <- function(name, env = .pkgenv) {
if (identical(env, emptyenv())) {
NULL
} else if (identical(env, globalenv())) {
# stop at global env
NULL
} else if (exists(name, envir=env, inherits = FALSE)) {
env[[name]]
} else {
# try parent
get1(name, parent.env(env))
}
}
这里我们只检查null,而不是单独验证名称,然后检索值。如果<代码> GET1是一个被称为一堆的东西,你可能想考虑缓存结果,这样你就不必总是要继承继承树。< /P>你有一个你正在研究的函数冲突的实际例子吗?我们可以用来测试这个问题。
在包内定义,而不是在包外定义(即在全局环境中)<代码>是(1,“数字向量”)
将返回TRUE
但我希望它返回FALSE
,因为继承(1,“数字向量”)
是FALSE
。这很有帮助,谢谢。是否有办法限制环境get0()
使用其envir
和继承的参数进行搜索?如果用户附加了一个包含is\u numeric\u vector()
的包,那么is\u()
不会仍然拾取它,因为它的环境是它来自的包,而不是全局环境?用户附加的包不应该在继承链中。如果你发现一个反例,请分享。没有办法改变get0的工作方式,因为这就是BaseR的工作方式。如果您喜欢手动迭代专利环境,您可以编写自己的。这发生在我自己的R包中,WeightIt
。我使用的is_u1;()
函数与我在这里发布的函数类似,但将paste0(“is.”,class)
替换为paste0(“is_1;,class)
。purrr
包有一个函数,是\u numeric()
,它会产生一个“弃用”警告。当用户附加purr
并且运行is_x(numeric”)
时,purr:is_numeric()
由get0()检索。您的解决方案不会阻止这种情况,因为purrr:is\u numeric()
不在全局环境中。确定。我的父订单搞错了,所以是的,附加的包成为了全球环境的父项。因此,在全球环境中没有停止搜索的通用方法。我更新了我的答案,使用了一个替代get0
的选项,该选项将在全局环境中停止。
# These are private helpers that do not need to be exported from your package.
.pkgenv <- environment()
get1 <- function(name, env = .pkgenv) {
if (identical(env, emptyenv())) {
NULL
} else if (identical(env, globalenv())) {
# stop at global env
NULL
} else if (exists(name, envir=env, inherits = FALSE)) {
env[[name]]
} else {
# try parent
get1(name, parent.env(env))
}
}
is_ <- function(obj, class) {
if (!is.null(fn <- get1(paste0("is.", class)))) {
fn(obj)
} else {
inherits(obj, class)
}
}