如何从 Rcpp 访问包中本地定义的环境?

How to access an environement locally defined in a package from Rcpp?

我有一个定义本地环境的包 选项。用 R 编写的同一包中的函数可以访问此环境 而无需 导出它:

options <- new.env()
options$foo <- "bar"

foobar <- function() {
    flag = options$foo == "bar"
    flag
}

当我尝试从 Rcpp 做同样的事情时:

bool foobar() {
    bool flag = false;
    Environment env("package:myPackage");
    SEXP o = env.get("options");
    Environment options(o);
    if (options.exists("foo")) {
        std::string bar = as<std::string>(options["foo"]);
        flag = (bar == "bar");
    }
    return flag;
}

如果我将 export(options) 添加到 NAMESPACE,则此 only 有效。所以我自己解决了这个问题,但很想知道这种明显的不对称性是否 w.r.t。导出要求是预期的,还是我对 Rcpp 函数的实现是罪魁祸首?

您想从包的命名空间而不是附加的包环境中提取符号。

例如,比较这两种解析 utils:::argNames 的方法,它是 utils 命名空间中的未导出函数:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
SEXP ns_symbol(const std::string& pkg, const std::string& symbol) {
   Environment env = Environment::namespace_env(pkg);
   return env[symbol];
}

// [[Rcpp::export]]
SEXP pkg_symbol(const std::string& pkg, const std::string& symbol) {
   Environment env("package:" + pkg);
   return env[symbol];
}


/*** R
library(utils)
ns_symbol("utils", "argNames")
pkg_symbol("utils", "argNames")
*/

运行 Rcpp::sourceCpp() 给我:

> Rcpp::sourceCpp('lookup.cpp')

> library(utils)

> ns_symbol("utils", "argNames")
function (fname, use.arg.db = .CompletionEnv$settings[["argdb"]]) 
{
    if (use.arg.db) 
        args <- .FunArgEnv[[fname]]
    if (!is.null(args)) 
        return(args)
    args <- do.call(argsAnywhere, list(fname))
    if (is.null(args)) 
        character()
    else if (is.list(args)) 
        unlist(lapply(args, function(f) names(formals(f))))
    else names(formals(args))
}
<bytecode: 0x7ff40889e6d0>
<environment: namespace:utils>

> pkg_symbol("utils", "argNames")
NULL

如您所见,符号是在包的命名空间内解析的,而不是在附加环境中。