Bill Dunlap
2008-Sep-09 20:48 UTC
[Rd] should system.file(package="no such pkg", "no such file") warn or abort?
Currently
system.file(package="no such
pkg","no","such","file")
silently returns the empty string, "", if said file doesn't
exist. This forces the caller to check for "" or risk getting
a mysterious error message from a function requiring a file
name. E.g.,
> read.dcf(system.file(package="no such
pkg","DESCRIPTION"))
Error in gzfile(file, "r") : cannot open the connection
In addition: Warning message:
In gzfile(file, "r") :
cannot open compressed file '', probable reason 'No such file
or directory'
> readLines(system.file(package="no such
pkg","no","such","file"))
character(0)
Warning message:
In file(con, "r") :
file("") only supports open = "w+" and open =
"w+b": using the former
> read.table(system.file(package="no such
pkg","examples","data.txt"))
Error in read.table(system.file(package = "no such pkg",
"examples", "data.txt")) :
no lines available in input
In addition: Warning message:
In file(file, "r") :
file("") only supports open = "w+" and open =
"w+b": using the former
I think it would help if system.file(), by default, threw an error
in this case. It could have an argument to suppress the error
if the caller desires. I suppose it could just have a warning.
I've attached a prototype, with the new argument missingFileOK=FALSE.
(I don't like the name, but didn't take the time to come up with
something better.)
> read.table(system.file(package="no such
pkg","examples","data.txt"))
Error in system.file(package = "no such pkg", "examples",
"data.txt") :
Cannot find package "no such pkg"
> read.table(system.file(package="base", "no",
"such", "file"))
Error in system.file(package = "base", "no",
"such", "file") :
Cannot find file "no/such/file" in package "base"
> system.file(package="no such
pkg","examples","data.txt", missingFileOK=TRUE)
[1] ""
Is this sort of thing desirable? It would require changes to
code that calls system.file() and checks for its output being "",
but it would make code that doesn't make the check work better.
`system.file` <-
function (..., package = "base", lib.loc = NULL, missingFileOK =
FALSE)
{
if (nargs() == 0)
return(file.path(.Library, "base"))
if (length(package) != 1)
stop("'package' must be of length 1")
packagePath <- .find.package(package, lib.loc, quiet = TRUE)
if (length(packagePath) == 0) {
if (missingFileOK)
return("")
else
stop("Cannot find package ", dQuote(package))
}
FILES <- file.path(packagePath, ...)
present <- file.exists(FILES)
if (any(present))
FILES[present]
else if (missingFileOK)
""
else stop("Cannot find file ", dQuote(file.path(...)), " in
package ", dQuote(package))
}
The diffs are
--- system.file.R~ 2008-09-09 13:47:06.608527000 -0700
+++ system.file.R 2008-09-09 11:46:41.509481000 -0700
@@ -1,16 +1,23 @@
`system.file` <-
-function (..., package = "base", lib.loc = NULL)
+function (..., package = "base", lib.loc = NULL, missingFileOK =
FALSE)
{
if (nargs() == 0)
return(file.path(.Library, "base"))
if (length(package) != 1)
stop("'package' must be of length 1")
packagePath <- .find.package(package, lib.loc, quiet = TRUE)
- if (length(packagePath) == 0)
- return("")
+ if (length(packagePath) == 0) {
+ if (missingFileOK)
+ return("")
+ else
+ stop("Cannot find package ", dQuote(package))
+ }
FILES <- file.path(packagePath, ...)
present <- file.exists(FILES)
if (any(present))
FILES[present]
- else ""
+ else if (missingFileOK)
+ ""
+ else stop("Cannot find file ", dQuote(file.path(...)), " in
package ", dQuote(package))
}
----------------------------------------------------------------------------
Bill Dunlap
TIBCO Spotfire
bill at insightful dot com (for a while)
"All statements in this message represent the opinions of the author and
do
not necessarily reflect TIBCO Software Inc. policy or position."
