Discussion:
[Rcpp-devel] using an unloaded package's lazy-load data in Rcpp function
Wasey, Jack O
2018-04-14 05:10:21 UTC
Permalink
Dear all,

It seems I can reference lazy-loaded data from an unloaded, unattached package from R, but not using the equivalent Rcpp as described in the quickref document. I checked out: http://dirk.eddelbuettel.com/code/rcpp/html/Environment_8h_source.html and even the scant references to environments in the C API section of "Writing R Extensions" and doesn't see what I'm missing. I suspect this is a limitation of R's C interface, not necessarily Rcpp itself.

I use the package nycflights13 as an example. Running `sessionInfo()` shows the package nycflights13 is not loaded, then I run:
R --vanilla
a <- nycflights13::flights
Which completes without error. In Rcpp, I cannot even get a handle on the package namespace if it is not loaded.

Rcpp::cppFunction('Rcpp::Environment getUnloaded() { Rcpp::Environment env("package:nycflights13"); return env;}')
getUnloaded()
Error in getUnloaded() :
Cannot convert object to an environment: [type=character; target=ENVSXP].

library(nycflights13)
Rcpp::cppFunction('Rcpp::Environment getUnloaded() { Rcpp::Environment env("package:nycflights13"); return env;}')
getUnloaded()
<environment: package:nycflights13>
attr(,"name")
[1] "package:nycflights13"
attr(,"path")
[1] "/Library/Frameworks/R.framework/Versions/3.4/Resources/library/nycflights13"
I also found that simple using `loadNamespace` was insufficient for the Rcpp approach to work, but after `library` or `attachNamespace` the above function does work.

Am I treading in another rare code path? All I want to do is use a lazy-loaded data set in an Rcpp function when the package may not be loaded when called. Should I just be passing it as a parameter to the function? This seems ugly.

Using Rcpp 0.12.16, R 3.4.3 on Mac.

Any advice appreciated. Thanks,

Jack
Kevin Ushey
2018-04-16 02:18:31 UTC
Permalink
The environments called 'package:foo' are associated with attached
packages; that is, they're located on the search path. You likely want to
find the actual package namespace.

I think we have a static function Environment::namespace_env() for this. Or
you can just call back to R with requireNamespace().

Kevin
Post by Wasey, Jack O
Dear all,
It seems I can reference lazy-loaded data from an unloaded, unattached
package from R, but not using the equivalent Rcpp as described in the
quickref document. I checked out: http://dirk.eddelbuettel.com/
code/rcpp/html/Environment_8h_source.html and even the scant references
to environments in the C API section of "Writing R Extensions" and doesn't
see what I'm missing. I suspect this is a limitation of R's C interface,
not necessarily Rcpp itself.
I use the package nycflights13 as an example. Running `sessionInfo()`
R --vanilla
a <- nycflights13::flights
Which completes without error. In Rcpp, I cannot even get a handle on the
package namespace if it is not loaded.
Rcpp::cppFunction('Rcpp::Environment getUnloaded() { Rcpp::Environment
env("package:nycflights13"); return env;}')
getUnloaded()
Cannot convert object to an environment: [type=character; target=ENVSXP].
library(nycflights13)
Rcpp::cppFunction('Rcpp::Environment getUnloaded() { Rcpp::Environment
env("package:nycflights13"); return env;}')
getUnloaded()
<environment: package:nycflights13>
attr(,"name")
[1] "package:nycflights13"
attr(,"path")
[1] "/Library/Frameworks/R.framework/Versions/3.4/Resources/library/
nycflights13"
I also found that simple using `loadNamespace` was insufficient for the
Rcpp approach to work, but after `library` or `attachNamespace` the above
function does work.
Am I treading in another rare code path? All I want to do is use a
lazy-loaded data set in an Rcpp function when the package may not be loaded
when called. Should I just be passing it as a parameter to the function?
This seems ugly.
Using Rcpp 0.12.16, R 3.4.3 on Mac.
Any advice appreciated. Thanks,
Jack
_______________________________________________
Rcpp-devel mailing list
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
Jack Wasey
2018-04-16 19:48:42 UTC
Permalink
Thanks for the reply. The solution of requiring the namespace from within Rcpp hadn't occurred to me.

I had used Environment::namespace_env("pkg_name") before, but I think the problem here is that lazy-loaded (and maybe other elements we expect in R) are not available if this is done from Rcpp. E.g.

# (using R --vanilla)
Rcpp::cppFunction('Rcpp::Environment getUnloaded2() { return Rcpp::Environment::namespace_env("nycflights13"); }')
ls(envir = getUnloaded2())
# empty, whereas the following:

nycflights13::flights
# pulls the data, with the package not being loaded or attached.

To close this thread, I think what the latter command does differently to Rcpp is to load the package, because sessionInfo() after running the second command, includes nycflights13 in the section "loaded via a namespace (and not attached):" This is not the case after pulling the environment into an Rcpp variable.

Thanks again for steering me,
Jack
The environments called 'package:foo' are associated with attached packages; that is, they're located on the search path. You likely want to find the actual package namespace.
I think we have a static function Environment::namespace_env() for this. Or you can just call back to R with requireNamespace().
Kevin
Dear all,
It seems I can reference lazy-loaded data from an unloaded, unattached package from R, but not using the equivalent Rcpp as described in the quickref document. I checked out: http://dirk.eddelbuettel.com/code/rcpp/html/Environment_8h_source.html <http://dirk.eddelbuettel.com/code/rcpp/html/Environment_8h_source.html> and even the scant references to environments in the C API section of "Writing R Extensions" and doesn't see what I'm missing. I suspect this is a limitation of R's C interface, not necessarily Rcpp itself.
R --vanilla
a <- nycflights13::flights
Which completes without error. In Rcpp, I cannot even get a handle on the package namespace if it is not loaded.
Rcpp::cppFunction('Rcpp::Environment getUnloaded() { Rcpp::Environment env("package:nycflights13"); return env;}')
getUnloaded()
  Cannot convert object to an environment: [type=character; target=ENVSXP].
library(nycflights13)
Rcpp::cppFunction('Rcpp::Environment getUnloaded() { Rcpp::Environment env("package:nycflights13"); return env;}')
getUnloaded()
<environment: package:nycflights13>
attr(,"name")
[1] "package:nycflights13"
attr(,"path")
[1] "/Library/Frameworks/R.framework/Versions/3.4/Resources/library/nycflights13"
I also found that simple using `loadNamespace` was insufficient for the Rcpp approach to work, but after `library` or `attachNamespace` the above function does work.
Am I treading in another rare code path? All I want to do is use a lazy-loaded data set in an Rcpp function when the package may not be loaded when called. Should I just be passing it as a parameter to the function? This seems ugly.
Using Rcpp 0.12.16, R 3.4.3 on Mac.
Any advice appreciated. Thanks,
Jack
_______________________________________________
Rcpp-devel mailing list
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel <https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel>
Kevin Ushey
2018-04-16 21:35:11 UTC
Permalink
Sorry, you're correct -- lazy-loaded data gets extracted not from the
package namespace but from the 'lazydata' portion of the namespace info.

Ultimately, I think you'll just want to call back to R to get what you
want, e.g.

getExportedValue("nycflights13", "flights")
Post by Jack Wasey
Thanks for the reply. The solution of requiring the namespace from within
Rcpp hadn't occurred to me.
I had used Environment::namespace_env("pkg_name") before, but I think the
problem here is that lazy-loaded (and maybe other elements we expect in R)
are not available if this is done from Rcpp. E.g.
# (using R --vanilla)
Rcpp::cppFunction('Rcpp::Environment getUnloaded2() { return
Rcpp::Environment::namespace_env("nycflights13"); }')
ls(envir = getUnloaded2())
nycflights13::flights
# pulls the data, with the package not being loaded or attached.
To close this thread, I think what the latter command does differently to
Rcpp is to load the package, because sessionInfo() after running the second
command, includes nycflights13 in the section "loaded via a namespace (and
not attached):" This is not the case after pulling the environment into an
Rcpp variable.
Thanks again for steering me,
Jack
Post by Kevin Ushey
The environments called 'package:foo' are associated with attached
packages; that is, they're located on the search path. You likely want to
find the actual package namespace.
Post by Kevin Ushey
I think we have a static function Environment::namespace_env() for this.
Or you can just call back to R with requireNamespace().
Post by Kevin Ushey
Kevin
Dear all,
It seems I can reference lazy-loaded data from an unloaded,
unattached package from R, but not using the equivalent Rcpp as described
in the quickref document. I checked out: http://dirk.eddelbuettel.com/
code/rcpp/html/Environment_8h_source.html <http://dirk.eddelbuettel.com/
code/rcpp/html/Environment_8h_source.html> and even the scant references
to environments in the C API section of "Writing R Extensions" and doesn't
see what I'm missing. I suspect this is a limitation of R's C interface,
not necessarily Rcpp itself.
Post by Kevin Ushey
I use the package nycflights13 as an example. Running
R --vanilla
a <- nycflights13::flights
Which completes without error. In Rcpp, I cannot even get a handle
on the package namespace if it is not loaded.
Post by Kevin Ushey
Rcpp::cppFunction('Rcpp::Environment getUnloaded() {
Rcpp::Environment env("package:nycflights13"); return env;}')
Post by Kevin Ushey
getUnloaded()
Cannot convert object to an environment: [type=character;
target=ENVSXP].
Post by Kevin Ushey
library(nycflights13)
Rcpp::cppFunction('Rcpp::Environment getUnloaded() {
Rcpp::Environment env("package:nycflights13"); return env;}')
Post by Kevin Ushey
getUnloaded()
<environment: package:nycflights13>
attr(,"name")
[1] "package:nycflights13"
attr(,"path")
[1] "/Library/Frameworks/R.framework/Versions/3.4/Resources/library/
nycflights13"
Post by Kevin Ushey
I also found that simple using `loadNamespace` was insufficient for
the Rcpp approach to work, but after `library` or `attachNamespace` the
above function does work.
Post by Kevin Ushey
Am I treading in another rare code path? All I want to do is use a
lazy-loaded data set in an Rcpp function when the package may not be loaded
when called. Should I just be passing it as a parameter to the function?
This seems ugly.
Post by Kevin Ushey
Using Rcpp 0.12.16, R 3.4.3 on Mac.
Any advice appreciated. Thanks,
Jack
_______________________________________________
Rcpp-devel mailing list
forge.r-project.org>
Post by Kevin Ushey
https://lists.r-forge.r-project.org/cgi-bin/mailman/
listinfo/rcpp-devel <https://lists.r-forge.r-project.org/cgi-bin/mailman/
listinfo/rcpp-devel>
Loading...