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).