我需要构建许多具有许多不同参数的函数,尽管它们共享很多代码和结构。 为了避免重复,我认为我很聪明并且自己建立一个功能工厂(也就是封闭)。
我无法弄清楚如何在函数工厂中传递函数参数。
我的用例是一堆S3构造函数,它们共享相同的验证机制。 因此,我将以此为例来解释我的问题。
说,我有一个ClassA
和ClassB
,每个都需要在各自的构造函数中有自己的参数:
ClassA <- function(A_arg1, A_arg2) {
# some class-SPECIFIC construction magic happens, say
out <- list(A_arg1, A_arg2)
# some GENERAL construction magic happens
class(out) <- "ClassA"
return(out)
}
ClassB <- function(B_arg1, B_arg2) {
# some class-SPECIFIC construction magic happens, say
out <- B_arg1 + B_arg2
# some GENERAL construction magic happens
class(out) <- "ClassB"
return(out)
}
显然,我喜欢避免构造函数的 general 部分中的重复,因此可以像一样使用的函数工厂将是很好:
ClassA <- produce_class_constructor(classname = "ClassA", fun = function(A_arg1, A_arg2) {return(list(A_arg1, A_arg2))})
理想情况下,这应该产生与上述手动构造的ClassA
函数完全相同的函数,并将一般部分考虑在内。
这是我尝试构建该功能工厂:
produce_class_constructor <- function(classname, fun) {
class_specific_arguments <- formals(fun = fun) # this works just fine on the console
construct_class <- function(class_specific_arguments) {
# here runs the class-specific stuff
out <- fun(class_specific_arguments)
# here runs the general stuff
class(out) <- classname
}
}
然而,这不起作用,因为结果构造函数只有class_specific_arguments
- 参数,而不是实际的A_arg1
和A_arg2
。
有办法做到这一点吗? 我做错了吗?
(对我来说非常重要的是,生成的类构造函数具有正确命名的参数,因此...
方法无法工作)。
答案 0 :(得分:1)
这是我的尝试:
produce_class_constructor <- function(classname, fun) {
out_fun <- function() {
out_obj <- do.call(fun, as.list(environment()))
class(out_obj) <- classname
out_obj
}
formals(out_fun) <- formals(fun)
out_fun
}
ClassA <- produce_class_constructor(classname = "ClassA",
fun = function(A_arg1, A_arg2) {list(A_arg1, A_arg2)})
ClassA(1, 2)
#[[1]]
#[1] 1
#
#[[2]]
#[1] 2
#
#attr(,"class")
#[1] "ClassA"
ClassB <- produce_class_constructor(classname = "ClassB",
fun = function(B_arg1, B_arg2) {B_arg1 + B_arg2})
ClassB(B_arg2 = 2, 1)
#[1] 3
#attr(,"class")
#[1] "ClassB"
来自this question的as.list(environment())
的提示。请注意,您应该在该路径上格外小心,正如?formals
所说,&#34;这是
先进的,危险的编码&#34;。