如何避免评估和分析?

Jos*_*osh 14 eval r

我编写了一个函数,该函数可获取包含其他函数脚本的文件,并将这些函数存储在替代环境中,以免它们干扰整个全局环境。该代码有效,但包含以下三个实例eval(parse(...))

# sourceFunctionHidden ---------------------------
# source a function and hide the function from the global environment
sourceFunctionHidden <- function(functions, environment = "env", ...) {
    if (environment %in% search()) {
        while (environment %in% search()) {
            if (!exists("counter", inherits = F)) counter <- 0
            eval(parse(text = paste0("detach(", environment, ")")))
            counter <- counter + 1 
        }
        cat("detached", counter, environment, "s\n")
    } else {cat("no", environment, "attached\n")}
    if (!environment %in% ls(.GlobalEnv, all.names = T)) {
        assign(environment, new.env(), pos = .GlobalEnv)
        cat("created", environment, "\n")
    } else {cat(environment, "already exists\n")}
    sapply(functions, function(func) {
        source(paste0("C:/Users/JT/R/Functions/", func, ".R"))
        eval(parse(text = paste0(environment, "$", func," <- ", func)))
        cat(func, "created in", environment, "\n")
    })
    eval(parse(text = paste0("attach(", environment, ")")))
    cat("attached", environment, "\n\n")
}
Run Code Online (Sandbox Code Playgroud)

关于eval(parse(...))构造的次优性已经写了很多(请参见此处此处)。但是,我发现的讨论主要涉及替代的子集策略。eval(parse(...))我的代码中的第一个和第三个实例不涉及子集(第二个实例可能与子集有关)。

有没有一种方法来调用new.env(...)[environment name]$[function name] <- [function name]attach(...)而不诉诸eval(parse(...))?谢谢。

注意:我不想更改函数名称以.name将其隐藏在全局环境中

dww*_*dww 5

对于它的价值,该函数source实际上使用eval(parse(...)),尽管有些微妙。首先,.Internal(parse(...))用于创建表达式,经过更多处理后,这些表达式随后传递给eval。这样eval(parse(...))看来对于R核心团队来说已经足够了。

就是说,您无需花很多钱就可以将函数提供给新环境。 source提供了local可以用于此目的的参数。

local:TRUE,FALSE或环境,确定在何处评估解析的表达式。

一个例子:

env = new.env()
source('test.r', local = env)
Run Code Online (Sandbox Code Playgroud)

测试它的工作原理:

env$test('hello', 'world')
# [1] "hello world"
ls(pattern = 'test')
# character(0)
Run Code Online (Sandbox Code Playgroud)

以及在test.r其上使用此示例文件:

test = function(a,b) paste(a,b)
Run Code Online (Sandbox Code Playgroud)