Search code examples
roverloadingdevtoolsr-s3

Operator overload stops working in R package


I have a container class that is basically a list. Because I wanted to support subsetting, I have overloaded the subset [ operator (likely poorly implemented).

#' Constructor for spectra object
.spectra = function(n_spectrum = 0) {
    object        = vector(mode = "list", n_spectrum)
    class(object) = "spectra"
    return(object)
}

#' Operator overload
#' @export
`[.spectra` = function(x, i) {
    x = unclass(x)
    x = x[i]                  # Using the list's subset function
    class(x) = "spectra"
    return(x)                 # Should return a "spectra" object, not a list
}

Now, this works as expected when in my development environment (when I'm debugging the package). That is, if y_old is a spectra object and I do y_new = y_old[-1], y_new is still a spectra object.

However, when I compile the project as a package and install it, the subsetting operator returns a list instead of a spectra object.

Any clue of what is going on?

EDIT

I forgot to mention that I'm using RStudio and the devtools library.


Solution

  • This problem boils down to RStudio's default initialization of NAMESPACE when you choose to create a package. Inspecting the NAMESPACE file reveals:

    exportPattern("^[[:alpha:]]+")
    

    Which doesn't match the subset operator [, as MrFlick pointed out.

    You can either add names to NAMESPACE manually or you can get RStudio and Roxygen to do the work for you. In RStudio 0.99.902 you would:

    1. install.packages("roxygen2")
    2. Check Generate documentation with Roxygen in the menu Build > Configure Build Tools > Build Tools.
    3. Click on the Configure button and check the NAMESPACE file check box.

    Now you obviously have to add Roxygen documentation to your functions and remember to use the @export tag, e.g.:

    #' Print hi in R
    #' @export
    print_hi = function(x) print("hi")
    

    After building you should have a automatically generated NAMESPACE file. For instance:

    # Generated by roxygen2: do not edit by hand
    
    export(print_hi)