After working my way thru Detach several packages at once , I now wonder if there is a reason the following validation code in base::detach is the way it is, or if there's a bug?
(the function itself is 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")
It seems to me that, whether or not the "character.only" argument is set, it would be better to test is.character(name) prior to risking running substitute() on the name value. The documentation does not explicitly say that you MUST set character.only=TRUE when name is a string.
So, before I go off and submit a bug/enhancement request, is there a solid reason for the validation to be the way it is?
Edit: to comment on mnel's response, here's my test example.
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]"
So you see the problem. My input variable is a valid name, but failure to set character.only to TRUE causes an undesired deparse to take place, and match(name, search()) fails for obvious reasons.
It just seems to me that it would be easier for the user if is.character were checked first, albeit inside a tryCatch to deal with the situation mnel describes. Two reasons: 1) it's more "user friendly" if detach doesn't even need a character.only argument, and 2) the documentation at present doesn't warn that the user must set character.only==TRUE when the name argument is an object containing a character string (but not, I believe if it's a just plain string. Either detach(package:Hmisc) or detach("package:Hmisc") work, but as my example shows, not a reference to the same string).