Say that I have a C++ function dosomething(z)
that has a single input variable z
, but also a "free" variable located within it (say y
). I want to be able to design the scoping so that when I run the Rcpp function, it finds the free variable within the R function in which it is called.
function(x) {
y = x^2
Rcpp::sourceCpp('C:/Users/xxx/dosomething.cpp')
dosomething(z)
}
So in the above, I want the dosomething(z)
function to use the value of y defined within the R function? How do I use Rcpp's Environment capabilities to achieve this? At present I can only seem to get free variables working by finding them in the global environment (not directly within the R function).
Rcpp
does not have something to directly deal with this, but you could query the frames with sys.frames
from within the C++
function (you just have to know that Rcpp
adds 7 frames just to call sys.frames
), e.g:
#include <Rcpp.h>
using namespace Rcpp ;
Environment get_calling_env(){
Function sys_frames( "sys.frames" ) ;
List frames = sys_frames() ;
Environment parent = frames.size() == 7 ? R_GlobalEnv : frames[ frames.size() - 8 ] ;
return parent ;
}
// [[Rcpp::export]]
CharacterVector foo(){
Environment parent = get_calling_env() ;
return parent.ls(false) ;
}
get_calling_env
gives you the environment from where the function was called. So that we can for example get the list of variables from that environment:
> f <- function(){ y <- 2; foo() }
# called from a function that calls foo, we get y
> f()
[1] "y"
# if called from the top, we just get the global env
> foo()
[1] "f" "foo"