使 R 函数 return 成为 locked/immutable 列表
make R function return a locked/immutable list
我有一个 return 列表的功能。
我希望这个列表是不可变的,类似于 lockBinding 防止覆盖或编辑对象的方式。
这看起来像下面这样:
myfun <- function(x){
out <- list(a = 1, val = x)
make_read_only(out)
out
}
test <- myfun(9)
test$a
[1] 1
test$val
[1] 9
test
$a
[1] 1
$val
[1] 9
test$newval <- 7
Error:
其中 make_read_only()
只是一个函数或完成此任务的一些代码的替代。
我已经尝试使用 lockBinding,它可以完美地工作,但是 'lock' 在函数 return 输出后无法向上传递到父环境。
我也研究过尝试在父环境中锁定符号,但似乎没有办法从函数内部了解输出将分配给什么,而这需要作为 lockBinding 的参数。
似乎有一种方法可以通过 return 引用环境并使用 lockEnvironment() 锁定环境或做类似的事情来做到这一点,但我想听听有哪些选择在开始之前在那里完成这个。
类似地,使用 R6 似乎可以实现,但我宁愿避免使用 R6,因为此代码库的任何其他部分都不需要它,而且我只想听听有哪些选项可以实现此行为。
总之,该函数会return一个任意列表。此列表将至少有几层深度。
mylist <- myfun(list(b = list(c = 3), foo = "bar"))
用户应该能够以类似于当前美元符号访问
的直接方式访问 sublits/elements
mylist$a$b$c
[1] 3
应该不能编辑这个对象。
mylist$a <- 5
Error:
应该可以通过
删除对象
rm(mylist)
mylist
Error: object 'mylist' not found
所以我的问题是,R 中有哪些可用选项可以完成此操作?
实现此目的的一种方法是创建一个新的 class (locked
) 以及 [<-
、[[<-
和 $<-
的方法对于这个新 class,这将 return 一个错误。
例如:
`[[<-.locked` <- function(...) {stop("Can't assign into locked object")}
a<-list(a="a",b=2)
a
$a
[1] "a"
$b
[1] 2
class(a)<-"locked"
a[[1]]<-"moose"
Error in `[[<-.locked`(`*tmp*`, 1, value = "moose") :
Can't assign into locked object
a
$a
[1] "a"
$b
[1] 2
attr(,"class")
[1] "locked"
在这种情况下,您的 "make read only" 函数需要做的就是将对象的 class 重新定义为 locked
:
class(out)<-c("locked",class(out))
我有一个 return 列表的功能。 我希望这个列表是不可变的,类似于 lockBinding 防止覆盖或编辑对象的方式。
这看起来像下面这样:
myfun <- function(x){
out <- list(a = 1, val = x)
make_read_only(out)
out
}
test <- myfun(9)
test$a
[1] 1
test$val
[1] 9
test
$a
[1] 1
$val
[1] 9
test$newval <- 7
Error:
其中 make_read_only()
只是一个函数或完成此任务的一些代码的替代。
我已经尝试使用 lockBinding,它可以完美地工作,但是 'lock' 在函数 return 输出后无法向上传递到父环境。 我也研究过尝试在父环境中锁定符号,但似乎没有办法从函数内部了解输出将分配给什么,而这需要作为 lockBinding 的参数。
似乎有一种方法可以通过 return 引用环境并使用 lockEnvironment() 锁定环境或做类似的事情来做到这一点,但我想听听有哪些选择在开始之前在那里完成这个。 类似地,使用 R6 似乎可以实现,但我宁愿避免使用 R6,因为此代码库的任何其他部分都不需要它,而且我只想听听有哪些选项可以实现此行为。
总之,该函数会return一个任意列表。此列表将至少有几层深度。
mylist <- myfun(list(b = list(c = 3), foo = "bar"))
用户应该能够以类似于当前美元符号访问
的直接方式访问 sublits/elementsmylist$a$b$c
[1] 3
应该不能编辑这个对象。
mylist$a <- 5
Error:
应该可以通过
删除对象rm(mylist)
mylist
Error: object 'mylist' not found
所以我的问题是,R 中有哪些可用选项可以完成此操作?
实现此目的的一种方法是创建一个新的 class (locked
) 以及 [<-
、[[<-
和 $<-
的方法对于这个新 class,这将 return 一个错误。
例如:
`[[<-.locked` <- function(...) {stop("Can't assign into locked object")}
a<-list(a="a",b=2)
a
$a
[1] "a"
$b
[1] 2
class(a)<-"locked"
a[[1]]<-"moose"
Error in `[[<-.locked`(`*tmp*`, 1, value = "moose") :
Can't assign into locked object
a
$a
[1] "a"
$b
[1] 2
attr(,"class")
[1] "locked"
在这种情况下,您的 "make read only" 函数需要做的就是将对象的 class 重新定义为 locked
:
class(out)<-c("locked",class(out))