gpt4 book ai didi

R 语言函数工厂 : How to ensure safety?

转载 作者:行者123 更新时间:2023-12-04 16:56:54 27 4
gpt4 key购买 nike

问题
我想检查 R 中的函数工厂是否“安全”。这里的“安全”意味着工厂创建的函数的结果仅取决于它们的参数,而不取决于全局变量。
描述
这是一个不安全的工厂:

funfac_bad = function(){  
newfun = function()
return(foo)
return(newfun)
}
newfun 的返回值将取决于执行 newfun 时 foo 的值。如果 foo 碰巧未定义,它甚至可能通过错误。
现在 - 很明显 - 可以通过将 foo 绑定(bind)到工厂内的值来使这个工厂安全
funfac_good = function(){
foo = 4711
newfun = function()
return(foo)
return(newfun)
}
我想我可以通过检查工厂中的全局变量来验证安全性。确实:
> codetools::findGlobals(funfac_bad) 
[1] "{" "=" "foo" "return"
> codetools::findGlobals(funfac_good)
[1] "{" "=" "return"
但我的实际用例(要)复杂得多。工厂的功能依赖于数百行代码的子功能和变量。因此,我找到了定义,我的工厂原则上是这样的:
funfac_my = function(){
sys.source("file_foo.R", envir = environment())
newfun = function()
return(foo)
return(newfun)
}
当且仅当在“file_foo.R”中执行的代码将名称“foo”绑定(bind)到一个值时,这是一个安全工厂。
但是(很合乎逻辑) codetools::findGlobals将始终将“foo”报告为全局变量。
问题
在获取定义时,如何检测此类函数工厂的不安全行为?

最佳答案

为什么不确保为 foo 定义一个默认值?在采购外部文件之前在本地?例如,假设我有这个文件:
foo.R

foo <- "file foo"
和这个文件
bar.R
bar <- "bar"
如果我这样写我的函数工厂:
funfac_my <- function(my_path) {
foo <- "fun fac foo"
if(!missing(my_path)) sys.source(my_path, envir = environment())
function() foo
}
然后我得到以下结果:
foo <- "global foo"

funfac_my("foo.R")()
#> [1] "file foo"

funfac_my("bar.R")()
#> [1] "fun fac foo"

funfac_my()()
#> [1] "fun fac foo"
因此,输出永远不会依赖于全局环境中是否有一个名为“foo”的对象(除非您正在恶意运行的脚本寻找一个名为“foo”的全局对象来复制——但那大概就是你想要的通过无论如何采购该文件)
请注意,您可以通过添加行 if(foo == "fun fac foo") stop("object 'foo' not found") 将其设置为抛出错误而不是返回默认值。就在最后一行之前。因此,这会提示 foo即使在全局工作区中有一个名为 foo 的错误对象,也未找到。

关于R 语言函数工厂 : How to ensure safety?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63205381/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com