Reputation: 7800
My package's DESCRIPTION
file has httr
in its Imports directive:
Imports:
httr (>= 1.1.0),
jsonlite,
rstudioapi
httr
exports an S3method for length.path
.
S3method(length,path)
And it's defined as:
#' @export
length.path <- function(x) file.info(x)$size
In my package I have objects that I assign the class "path" to. Every time I assign the class "path" to any object, regardless of whether or not I ever call length()
on the object, this is printed to stdout:
Error in file.info(x) : invalid filename argument
Here's some reproducible code everyone can run:
> sessionInfo()
R version 3.3.1 (2016-06-21)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.11.5 (El Capitan)
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] tools_3.3.1
> thing = 1:5
> class(thing) = 'path'
> requireNamespace('httr')
Loading required namespace: httr
> sessionInfo()
R version 3.3.1 (2016-06-21)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.11.5 (El Capitan)
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] httr_1.2.1 R6_2.1.2 tools_3.3.1
> thing = 1:5
> class(thing) = 'path'
Error in file.info(x) : invalid filename argument
I've tried catching it in a try
but that doesn't work:
set_class = function(obj, c) {
class(obj) = c
return(obj)
}
thing = 1:5
thing = try(set_class(thing, 'path'), silent=TRUE)
Yields:
Error in file.info(x) : invalid filename argument
I've tried assignInNamespace
to override the function:
base_length = function(obj) {
return(base::length(obj))
}
assignInNamespace('length.path', base_length, 'httr')
thing = 1:5
class(thing) = 'path'
But I get Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
When I use httr
functions in my package I use them with httr::function
so I'm not sure how this length.path
function is leaking into my namespace and overriding the base length function. I've also tried explicit @importFrom httr function
for each function that I use instead of using httr::function
but that doesn't work either.
I also found this:
https://support.bioconductor.org/p/79059/
But the solution seemed to be to edit the source code of httr
, which I can't do since my package imports it. How can I get around this?
Upvotes: 6
Views: 719
Reputation: 7800
The solution for me was to add an .onLoad
function. Thanks to AEF's answer for the unclass
idea.
#' @importFrom utils assignInNamespace
.onLoad = function(libname, pkgname) {
length.path = function(obj) {
return(length(unclass(obj)))
}
assignInNamespace('length.path', length.path, 'httr')
}
It raises a NOTE
in R CMD check --as-cran
but I'm hoping to get away with it.
Upvotes: 0
Reputation: 5670
One possibility could be to create a function length.path()
in your own package. If the base type of your path
-objects is compatible with base::length()
you could just unclass it to avoid infinite recursion:
length.path <- function(x) length(unclass(x))
However, this is potentially slow compared to a direct call to base::length()
because it copies the object and needs method dispatch two times.
Upvotes: 1