Closed Tutuchan closed 7 years ago
The reason that the function factory doesn't work is because it generates a closure: the function that's returned by power
also has an enclosing environment that contains the value of exponent
. However, when the R6 object is instantiated by A$new()
, it copies the function but reassigns the function's environment -- that's how methods in R6 objects get scoped to the object. The reassigned environment also causes it to lose the enclosing environment with exponent
.
If you want something like this to work, you'd have to make a version of power
that, instead of simply using an enclosing environment to hold the value of exponent
, would actually alter the body of the function.
See these for more:
As for the "could not find function" problem, I'm not sure offhand why that's happening, as long as aaa.r is getting loaded before class.R. Perhaps the collate order in DESCRIPTION telling it to do something different?
Thanks for the explanation, that makes a lot of sense. I'll try out the examples you provided and report back.
For the 2nd problem, I don't really know either, my collate order is the default one so it should work. I'll take another look later.
Using pryr::unenclose
does the job very simply:
power <- function(exponent) {
function(x) {
x ^ exponent
}
}
A <- R6::R6Class(
"A",
public = list(
square = power(2),
usquare = pryr::unenclose(power(2))
)
)
test <- A$new()
test$square(4)
#> Error in test$square(4): object 'exponent' not found
test$usquare(4)
#> [1] 16
For the second problem, it indeed comes from the collate directive because some of my files starts with uppercase letters so they are loaded before aaa.R
.
Thanks again for pointing me in the right direction.
I'm tryring to define methods in a R6 class based on a function factory and I encounter errors. Here is a reproducible example.
Furthermore, I'm doing this in a package. The function factory is defined in
aaa.R
and my class inclass.R
and trying toinstall()
ordocument()
the package leads toMaybe I'm missing something but do you have any idea how to make this work ?