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

时间:2016-04-28 10:17:42

标签: r package environment 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;
}
如果我将导出(选项)添加到NAMESPACE,

有效。所以我自己解决了这个问题,但我很想知道这种明显的不对称是否存在。出口要求是预期的还是我的Rcpp功能的实施应该归咎于什么?

1 个答案:

答案 0 :(得分:3)

您希望从包的名称空间中提取符号,而不是附加的包环境。

例如,比较这两种方法来解析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

如您所见,该符号已在包的命名空间内解析,但未在附加环境中解析。