In one of my packages I use the .onAttach
hook to run some R code and then use assign
to make the value available as one of the package variables. I do it because variable
depends on the content of some file, which can change between one session and the other. The code I use is like:
.onAttach <- function(libname, pkgname) {
variable <- some_function()
assign("variable", variable, envir = as.environment("package:MyRPackage"))
}
When I attach the package with library(MyRpackage)
I can use variable
.
However it is not possible to do something like MyRPackage::variable
(unless I have already attached the package with library(MyRpackage)
.
I know this is because I should put that code in the .onLoad
hook, however I can't make the assignment so that it works.
I have tried
.onLoad <- function(libname, pkgname) {
variable <- some_function()
assign("variable", variable, envir = as.environment("namesoace:MyRPackage"))
}
and
.onLoad <- function(libname, pkgname) {
variable <- some_function()
assign("variable", variable, envir = asNamespace("MyRPackage"))
}
but both of them fail with some error when I run MyRPackage:::variable
without using library
to attach the package.
What is the correct to do the assignment in the .onLoad hook?
Following the approach in this answer to a related question, you can change your .onLoad()
function like so:
.onLoad <- function(libname, pkgname) {
variable <- some_function()
assign("variable", variable, envir = parent.env(environment()))
}
Then you can access variable
without attaching the package using MyRPackage:::variable
. I don't know what you do with some_function()
, so I tried the following with a dummy package:
.onLoad <- function(libname, pkgname) {
variable <- 42
assign("variable", variable, envir = parent.env(environment()))
}
And in a fresh R session the result was
> MyRPackage:::variable
[1] 42
From Hadley Wickham's Advanced R:
There are four special environments:
...
- The environment() is the current environment.
...
You can list the bindings in the environment’s frame with ls() and see its parent with parent.env().
So, if we modify the .onLoad()
function further, we can see this in action:
.onLoad <- function(libname, pkgname) {
print(environment()) # For demonstration purposes only;
print(parent.env(environment())) # Don't really do this.
variable <- 42
assign("variable", variable, envir = parent.env(environment()))
}
Then starting an R session results in
<environment: 0x483da88>
<environment: namespace:MyRPackage>
being printed to the console at the start of the session. This allows you to assign variable
in the environment namespace:MyRPackage
even though trying assign("variable", variable, envir = namespace:MyRPackage)
would result in the error
Error: package or namespace load failed for ‘MyRPackage’:
.onLoad failed in loadNamespace() for 'MyRPackage', details:
call: get(name, envir = ns, inherits = FALSE)
error: object 'namespace' not found
when installing the package.