Closed mllg closed 5 years ago
It looks like this is what R does in packages: active bindings get saved as regular values.
If you add this to your package, the same thing happens:
#' @export
e <- new.env()
makeActiveBinding("x", function() runif(1), e)
Then after installing the package:
e$x
#> [1] 0.1425588
e$x
#> [1] 0.1425588
bindingIsActive("x", e)
#> [1] FALSE
Perhaps it's worth asking about on the R-devel mailing list?
Can confirm this one. I've updated the package to also include your code.
> library(r6pkg)
> unique(replicate(10, r6$x))
[1] 0.5698038
> unique(replicate(10, env$x))
[1] 0.262672
@kalibera, is this related to the bytecode compiler?
NB: saveRDS()
+ loadRDS()
is not affected.
Active bindings are preserved on serialization/deserialization, but one has to serialize them as bindings (not values) - so one has to serialize at least the environment they are part of.
Active bindings are however not preserved when a package is being prepared for lazy loading (during package installation). The lazy loading database is already created with concrete values for active bindings.
So this is a feature, not a bug? 😕
Workaround: construct objects with active bindings in .onLoad()
.
It is probably unintentional, but may not be trivial to fix (could impact performance of package installation, would require some change in lazy loading database format). So if you can use .onLoad
that would be great and would also work for released versions of R.
Here is a small package to illustrate the issue:
https://github.com/mllg/r6pkg
Everything works out fine while loading the package interactively (using devtools'
load_all()
):The active binding is lost after installing and loading the package in a fresh R session via
library()
:Looks like the binding gets evaluated during R CMD build and the returned value is stored instead.