经过Detach several packages at once的工作之后,我现在想知道base::detach
中的以下验证代码是否是这样的原因,还是存在错误?
(函数本身是detach(name, pos = 2L, unload = FALSE, character.only = FALSE, force = FALSE)
)
if (!missing(name)) {
if (!character.only)
name <- substitute(name)
pos <- if (is.numeric(name))
name
else {
if (!is.character(name))
name <- deparse(name)
match(name, search())
}
if (is.na(pos))
stop("invalid 'name' argument")
在我看来,无论是否设置了“character.only”参数,在冒险对
is.character(name)
值运行substitute()
之前,最好先测试name
。文档没有明确指出当character.only=TRUE
是字符串时,您必须设置name
。因此,在我提交错误/增强请求之前,是否有充分的理由使验证保持原样?
编辑:评论mnel的响应,这是我的测试示例。
Rgames> detlist<-c('Hmisc','survival','splines')
Rgames> library(Hmisc)
Rgames> debug(base::detach)
Rgames> base::detach(detlist[1])
# skipped the startup stuff.
Browse[2]>
debug: if (!character.only) name <- substitute(name)
Browse[2]> name
[1] "Hmisc"
Browse[2]>
debug: name <- substitute(name)
Browse[2]>
debug: pos <- if (is.numeric(name)) name else {
if (!is.character(name))
name <- deparse(name)
match(name, search())
}
Browse[2]> name
detlist[1]
Browse[2]>
debug: if (!is.character(name)) name <- deparse(name)
Browse[2]>
debug: name <- deparse(name)
Browse[2]> deparse(name)
[1] "detlist[1]"
所以你看到了问题。我的输入变量是一个有效的名称,但是未将
character.only
设置为TRUE
会导致发生不希望的deparse
,并且match(name, search())
出于明显的原因而失败。在我看来,如果首先检查
is.character
,对用户来说会更容易,尽管在tryCatch
内处理了mnel描述的情况。原因有两个:1)如果detach
甚至不需要character.only
参数,则对用户更友好;以及2)当character.only==TRUE
参数是包含以下内容的对象时,当前文档没有警告用户必须设置name
字符串(但不是,我相信这只是一个普通的字符串。detach(package:Hmisc)或detach(“package:Hmisc”)都可以,但是如我的示例所示,不是对同一字符串的引用。 最佳答案
除非您知道name
参数仅是字符,否则不必冒险评估它。
请注意,help('detach')
将name
参数描述为
这可以是未加引号的名称或字符串,但不能是字符向量。如果提供了数字,则将其视为pos。is.character
将评估其参数,而替代者则不会。如果name
不是字符串,则它将是未加引号的字符串(例如package:stats
)。如果要测试is.character(x = package:stats)
,这将尝试评估package:stats
(即对`:`(package,stats)
的调用。这将不是很好的选择(并且会返回错误或无意义的内容,具体取决于您的搜索路径上是否有package
和stats
的值) )。
使用character.only
,意味着substitute
将被调用(不会评估该参数),但是将返回language
类型的对象(如果原始名称是未引用的名称)或字符串(如果原始是字符串)。无论结果如何,name
都可以是deparsed
以创建所需的字符串。
您可以通过调用browser
的适当位置创建函数来跟踪正在发生的事情
例如
d <- function (name, pos = 2L, unload = FALSE, character.only = FALSE,
force = FALSE) {
if (!missing(name)) {
browser()
if (!character.only)
name <- substitute(name)
pos <- if (is.numeric(name))
name
else {
if (!is.character(name))
name <- deparse(name)
match(name, search())
}
if (is.na(pos))
stop("invalid 'name' argument")
}
return(list(name, pos))
}
# called using an unquoted string.
d(package:stats, pos = 2L)
# Called from: d(package:stats, pos = 2L)
# Browse[1]> n
# debug at #7: if (!character.only) name <- substitute(name)
# Browse[2]> str(name)
# Error in str(name) : object 'package' not found
# Browse[2]> n
# debug at #7: name <- substitute(name)
# Browse[2]> n
# debug at #9: pos <- if (is.numeric(name)) name else {
# if (!is.character(name))
# name <- deparse(name)
# match(name, search())
# }
# Browse[2]> str(name)
# language package:stats
# Browse[2]> n
# debug at #12: if (!is.character(name)) name <- deparse(name)
# Browse[2]> n
# debug at #12: name <- deparse(name)
# Browse[2]> n
# debug at #14: match(name, search())
# Browse[2]> n
# debug at #16: if (is.na(pos)) stop("invalid 'name' argument")
# Browse[2]> n
# debug at #16: NULL
# Browse[2]> str(name)
# chr "package:stats
# Browse[2]> Q
d('package:stats', pos = 2L)
# Called from: d("package:stats", pos = 2L)
# Browse[1]> n
# debug at #7: if (!character.only) name <- substitute(name)
# Browse[2]> n
# debug at #7: name <- substitute(name)
# Browse[2]> n
# debug at #9: pos <- if (is.numeric(name)) name else {
# if (!is.character(name))
# name <- deparse(name)
# match(name, search())
# }
# Browse[2]> str(name)
# chr "package:stats"
# Browse[2]> Q
根据已编辑的问题进行编辑。
可能在帮助文件中描述
name
的方式应与“package in
包的定义要求&
库(which have similar methods of dealing with
名称and
character.string”样式参数的定义保持一致。即
包的名称,以名称或文字字符串形式给出,或
字符串,取决于character.only是否为FALSE
(默认)或TRUE)。
help('detach')
中的当前定义使用character string
隐含一个文字字符串,该字符串包含您想要搜索的搜索路径上的项目名称。detach
和character vector
定义一个字符向量,其中包含一个字符串,该字符串是搜索路径上该项目的名称你想detach
。我将
help('detach')
中的定义更改为这可以是未加引号的名称或文字字符串。如果是
character.only == TRUE
,则可以提供长度为1的字符向量。如果提供了数字,则将其视为pos。
或类似的方法可能会有所帮助。
关于r - 为什么base::detach验证名称的输入方式呢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17554597/