如何从 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
如您所见,符号是在包的命名空间内解析的,而不是在附加环境中。
我有一个定义本地环境的包 选项。用 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
如您所见,符号是在包的命名空间内解析的,而不是在附加环境中。