In my toy package, I have defined %+%
operator as an alias to paste0()
. Trying to reduce interference with other packages, I realized it the following way:
`%+%` <- function(...) UseMethod("%+%")
`%+%.character` <- paste0
`%+%.numeric` <- paste0
`%+%.default` <- function (arg1, arg2){
e <- parent.env(getEnvByName(.GlobalEnv,'package:mypackagename'));
if (exists('%+%', envir = e)) get('%+%',envir = e)(arg1,arg2);
}
i.e. I override it only for character
and numeric
arguments, otherwise it tries to find if the method was previously defined.
It was working just fine until recently when it started giving an error:
'a' %+% 'b'
# Error in UseMethod("%+%") :
# no applicable method for '%+%' applied to an object of class "character"
It only fails when called outside of the package. If I define a function within the package, it works correctly:
# testab2() is defined in R file as a part of the package:
testab2 <- function(inpA, inpB){
print (inpA %+% inpB)
}
# when called outside of the package:
testab2('a','b')
# ab
I am pretty sure I didn't change anything in my code, so I'm wondering if it could be caused by R update. What could have changed and how to make it work back?
P.S. getEnvByName()
is my helper function that searches for an object in parent environments:
getEnvByName <- function(inpEnv=.GlobalEnv, lookFor){
e <- inpEnv;
while (environmentName(e) != 'R_EmptyEnv' & environmentName(e)!=lookFor) e <- parent.env(e);
if (environmentName(e) != lookFor) return(NULL);
return(e);
}
And the exporting was done by the following lines in the NAMESPACE
file:
exportPattern("^[[:alpha:]]+")
exportPattern("%.*%")
export("%+%.default")
export("%+%.character")
P.P.S. sessionInfo:
R version 4.0.2 (2020-06-22)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18363)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C LC_TIME=English_United States.1252
system code page: 1251
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] vautils_0.1.1.105 magrittr_1.5 data.table_1.13.0
loaded via a namespace (and not attached):
[1] dplyr_1.0.2 crayon_1.3.4 grid_4.0.2 R6_2.4.1 lifecycle_0.2.0 gtable_0.3.0
[7] scales_1.1.1 ggplot2_3.3.2 pillar_1.4.6 rlang_0.4.7 rstudioapi_0.11 generics_0.0.2
[13] vctrs_0.3.4 ellipsis_0.3.1 tools_4.0.2 glue_1.4.2 purrr_0.3.4 munsell_0.5.0
[19] compiler_4.0.2 pkgconfig_2.0.3 colorspace_1.4-1 tidyselect_1.1.0 tibble_3.0.3
To export S3 methods, your NAMESPACE
file needs to (in your case) contain the following declarations:
export(`%+%`)
S3method(`%+%`, default)
S3method(`%+%`, character)
S3method(`%+%`, numeric)
That is, export the %+%
generic, and declare S3 methods for the methods.
Better yet, instead of manually editing the NAMESPACE
file use ‘roxygen2’, which generates the correct declarations for you based on the @export
documentation tag.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With