Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

defining operator doesn't work anymore (Error in UseMethod("%op%"): no applicable method for '%op%' applied to an object of class "character")

Tags:

r

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 
like image 876
Vasily A Avatar asked Oct 02 '20 09:10

Vasily A


1 Answers

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.

like image 93
Konrad Rudolph Avatar answered Oct 21 '22 18:10

Konrad Rudolph