我有一个定义本地环境选项的包。用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功能的实施应该归咎于什么?
答案 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
如您所见,该符号已在包的命名空间内解析,但未在附加环境中解析。