3

在通过 一次分离几个包的方式工作之后,我现在想知道下面的验证代码是否有原因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=TRUEwhenname是一个字符串。
那么,在我开始提交错误/增强请求之前,是否有充分的理由让验证成为这种方式?

编辑:评论 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.onlyTRUE 会导致不希望deparse的情况发生,并且match(name, search())由于明显的原因而失败。
在我看来,如果is.character首先检查用户会更容易,尽管在 atryCatch内处理 mnel 描述的情况。detach两个原因:1)如果甚至不需要参数,它会更加“用户友好” character.only,以及 2)目前的文档没有警告用户必须设置参数是一个包含字符串的对象(但不是,我相信如果它只是一个普通字符串。无论是 detach(package:Hmisc) 还是 detach("package:Hmisc") 都可以,但正如我的示例所示,不是对同一字符串的引用)。character.only==TRUE在何时name

4

1 回答 1

1

name除非您知道它只是性格,否则不要冒险评估论点。

请注意,help('detach')name参数描述为

这可以是不带引号的名称或字符串,但不能是字符向量。如果提供了一个数字,则将其视为 pos。

is.character将评估其论点,而替代不会。如果name不是字符串,它将是不带引号的字符串(例如package:stats)。如果您要测试is.character(x = package:stats),这将尝试评估package:stats(即调用`:`(package,stats). 这不会很好(并且会返回错误或无意义的东西,具体取决于您的搜索路径是否有值package和可用)。stats

using 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 inrequire &library (which have similar methods of dealing withname andcharacter.string` 样式参数的定义一致

IE

包的名称,以名称或文字字符串或字符串形式给出,具体取决于 character.only 是 FALSE(默认值)还是 TRUE)。

中的当前定义help('detach')用于character string暗示包含您希望搜索路径上的项目名称的文字字符串,detachcharacter vector定义包含字符串的字符向量,该字符串是您希望搜索路径上的项目名称detach

我将定义更改help('detach')

这可以是不带引号的名称或文字字符串。如果character.only == TRUE则可以提供长度为 1 的字符向量。如果提供了一个数字,则将其视为 pos。

或类似的可能会有所帮助。

于 2013-07-11T02:28:08.827 回答