Losing imported module in functions when adding functions to a class using R6$set
#382
-
I’ve run into a problem while trying to combine The issue seems to be tied to how environments are managed when a function from a The ProblemHere’s the setup I’m working with:
When I call the method on an R6 object, I get this error:
Minimal Reproducible ExampleFile: #' @export
VALID_COLORS <- list(
RED = "red",
GREEN = "green",
BLUE = "blue"
) File: box::use(./constants)
#' @export
.validate_color <- function(color) {
if (!color %in% constants$VALID_COLORS) {
stop("Invalid colour: ", color)
}
} File: box::use(R6, ./validators)
#' @export
MyClass <- R6$R6Class(
"MyClass",
public = list(
set_color = function(color) {
private$.validate_color(color)
private$.color <- color
}
),
private = list(
.color = NULL
)
)
MyClass$set("private", ".validate_color", validators$.validate_color) File: box::use(./MyClass)
obj <- MyClass$MyClass$new()
obj$set_color("red") When I run
What I Think Might Happening?After poking around online and reading up on how
I think I just have to change the way I do imports, I did get a set up similar to this working earlier but I can remember how, I am searching through my commits to try to find it - the truth is I don't really understand how this is working/not working. R version 4.5.0 (2025-04-11)
Platform: aarch64-apple-darwin20
Running under: macOS Sequoia 15.4.1
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: America/Chicago
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] crayon_1.5.3 vctrs_0.6.5 dereck_2.0.1
[4] cli_3.6.5 rlang_1.1.6 DBI_1.2.3
[7] stringi_1.8.7 generics_0.1.4 jsonlite_2.0.0
[10] data.table_1.17.0 glue_1.8.0 listenv_0.9.1
[13] future.apply_1.11.3 scales_1.4.0 grid_4.5.0
[16] tibble_3.2.1 MASS_7.3-65 lifecycle_1.0.4
[19] box_1.2.0 stringr_1.5.1 compiler_4.5.0
[22] codetools_0.2-20 fs_1.6.6 RColorBrewer_1.1-3
[25] timechange_0.3.0 Rcpp_1.0.14 pkgconfig_2.0.3
[28] future_1.49.0 farver_2.1.2 digest_0.6.37
[31] R6_2.6.1 pillar_1.10.2 parallelly_1.44.0
[34] parallel_4.5.0 magrittr_2.0.3 tools_4.5.0
[37] gtable_0.3.6 stenographer_1.0.2 globals_0.18.0
[40] lubridate_1.9.4 ggplot2_3.5.2 |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
This is interesting, I very quickly stumbled upon the solution but I don't understand why it works. I had to import constants into where the class is and the functions are attached with # ./MyClass.R
box::use(R6, ./validators, ./constants)
#' @export
MyClass <- R6$R6Class(
"MyClass",
public = list(
set_color = function(color) {
private$.validate_color(color)
private$.color <- color
}
),
private = list(
.color = NULL
)
)
MyClass$set("private", ".validate_color", validators$.validate_color) |
Beta Was this translation helpful? Give feedback.
-
That’s exactly right. In my opinion this is a seriously questionable design decision of R6, but here we are. My suggestion would be not to attach named functions to R6 classes. Instead, you can dispatch via an anonymous function, e.g.: MyClass$set("private", ".validate_color", \(c) validators$.validate_color(c)) That said, your solution works as well. The reason it works is that importing |
Beta Was this translation helpful? Give feedback.
That’s exactly right. In my opinion this is a seriously questionable design decision of R6, but here we are.
My suggestion would be not to attach named functions to R6 classes. Instead, you can dispatch via an anonymous function, e.g.:
That said, your solution works as well. The reason it works is that importing
./constants
makes the nameconstants
available in the module environment whereMyClass
is defined. With that,MyClass$.validate_color
will be able to find that name, since the module environment is an enclosing (/parent) environment of theMy…