rr-packager6

How to include an R6Class that uses internal data in an R package?


I have followed Konrad Rudolph's comment to move the sysdata.R file to the data-raw folder (DATASET.R now), but the issue is not related to this but caused by the R6 object defined in problem_R6.R.

Please find the updated example below:

I am learning R6 and trying to create a simple R6Class that uses internal variables defined in data-raw/DATASET.R.

My example package is really simple, based on the default R package template. It only contains three R files that I wrote. They are:

data-raw/DATASET.R, for creating the internal variables:

internal_name  <- "Eric"

usethis::use_data(internal_name, internal = TRUE, overwrite = TRUE)

R6_Class_1.R, for getting the internal variable internal_name:

#' @import R6
#'
#' @noRd

name <- R6::R6Class(

  classname = "name",

  private = list( target_name = NULL),


  public = list(

    initialize = \(text) { private$target_name <- text },

    get_name = \() { private$target_name }
  )
)

problem_R6.R, to generate greeting message:

#' @import R6
#'
#' @noRd


greeting <- R6::R6Class(

  classname = "greeting",

  private = list(

    name = name$new(text = internal_name)
  ),


  public = list(

    message = NULL,

    initialize = \() { self$message = "Hello! " },

    greet = \() { paste0(self$message, private$name$get_name(), "!") }
  )
)

However, whenever I try to clean and install the package, I get an error saying that the object is not found:

Error in eval(exprs[i], envir) : object 'internal_name' not found
Error: unable to load R code in package 'testingR6'
Execution halted
ERROR: lazy loading failed for package 'testingR6'
* removing 'C:/Users/.../R/win-library/4.4/testingR6'
* restoring previous 'C:/Users/H.../R/win-library/4.4/testingR6'

Exited with status 1.

The package structure is shown below, it can also be found in github:

> fs::dir_tree()
.
├── data-raw
│   └── DATASET.R
├── DESCRIPTION
├── man
├── NAMESPACE
├── R
│   ├── problem_R6.R
│   ├── R6 Class 1.R
│   └── sysdata.rda
└── testingR6.Rproj

I have no idea what is causing the issue— sysdata.rda is created from data-raw/DATASET.R, and the variable internal_name is there when I load the .rda file. I'm just wondering how to fix the error so the package can include the problem R6 object?


Solution

  • After six months of trial and error, I finally figured out the issue. Using NULL as a placeholder and leaving the definition to the public initialize() method prevents evaluation during the package build process.

    name <- R6::R6Class(
      classname = "name",  
      private = list( target_name = NULL),    
      public = list(    
        initialize = \(text) { private$target_name <- text },    
        get_name = \() { private$target_name }
      )
    )
    
    im_here <- name$new(text = "Eric")
    
    greeting <- R6::R6Class(  
      classname = "greeting",  
      private = list(    
        name = NULL  # <- here 
      ),  
      public = list(    
        message = NULL,
        initialize = \(input_R6) {   # <- notice here      
          private$name <- input_R6   # <- notice here      
          self$message = "Hello! " },
        greet = \() { paste0(self$message, private$name$get_name(), "!") }
      )
    )
    
    you_are_here <- greeting$new(input_R6 = im_here)
    
    you_are_here$greet()