'unlockEnvironment' implemented via 'Rcpp' instead of 'inline'

前端 未结 1 1094
后悔当初
后悔当初 2020-12-21 02:55

Actual question

Could someone get me started on what I need to do to implement the code of unlockEnvironment below in Rcpp?

Background

相关标签:
1条回答
  • 2020-12-21 03:22

    It sounds like your question basically amounts to, 'how do I use Rcpp::attributes'? And I would suggest that you go over many of the examples in the Rcpp Gallery to learn a bit more.

    The main idea: write some C++ code, put it a .cpp file, then call Rcpp::sourceCpp(<file>) to load it. For this particular example:

    #include <Rcpp.h>
    using namespace Rcpp;
    
    /* This is taken from envir.c in the R 2.15.1 source
    https://github.com/SurajGupta/r-source/blob/master/src/main/envir.c
    */
    #define FRAME_LOCK_MASK (1<<14)
    #define FRAME_IS_LOCKED(e) (ENVFLAGS(e) & FRAME_LOCK_MASK)
    #define UNLOCK_FRAME(e) SET_ENVFLAGS(e, ENVFLAGS(e) & (~ FRAME_LOCK_MASK))
    
    // [[Rcpp::export]]
    bool unlock_environment(Environment env) {
      UNLOCK_FRAME(env);
      return FRAME_IS_LOCKED(env) == 0;
    }
    
    /*** R
    env <- new.env()
    lockEnvironment(env)
    try(env$a <- 1) ## error
    unlock_environment(env)
    env$a <- 1
    */
    

    Calling Rcpp::sourceCpp() on a file with these contents gives me:

    > Rcpp::sourceCpp('~/scratch/unlock.cpp')
    
    > env <- new.env()
    
    > lockEnvironment(env)
    
    > try(env$a <- 1) ## error
    Error in env$a <- 1 : cannot add bindings to a locked environment
    
    > unlock_environment(env)
    [1] TRUE
    
    > env$a <- 1 ## success!
    

    The main little features here:

    1. You can provide signatures using base / STL C++ types, or Rcpp types as well. Note that bool is the C++ bool type, and Environment is an Rcpp type encompassing environments.
    2. Rcpp Attributes handles automatic conversion of these C++ return types to R's SEXP.

    You might like Hadley's adv-r introduction as well.

    0 讨论(0)
提交回复
热议问题