定义调用 R6 对象之外的其他方法的方法
Defining methods that call other methods outside of R6 objects
使用 R6 classes 时,在 class 之外定义调用其他方法的方法的正确方法是什么?
考虑以下示例,其中函数 func
如果以交互方式使用,可能会分派给另一个函数。但是,如果这样做,其他功能将无法访问私有环境。如果我以这种方式定义 classes,我应该传递一个环境吗?
## General function defined outside R6 class
func <- function(x) {
if (missing(x) && interactive()) {
ifunc()
} else {
private$a <- x * x
}
}
## If interactive, redirect to this function
ifunc <- function() {
f <- switch(menu(c('*', '+')), '1'=`*`, '2'=`+`)
private$a <- f(private$a, private$a)
}
## R6 test object
Obj <- R6::R6Class("Obj",
public=list(
initialize=function(a) private$a <- a,
geta=function() private$a,
func=func # defined in another file
),
private=list(
a=NA
)
)
## Testing
tst <- Obj$new(5)
tst$func(3)
tst$geta() # so func sees 'private'
# [1] 9
tst$func() # doesn't see 'private'
Error in ifunc() (from #3) : object 'private' not found
您面临的问题是您定义 func
和 ifunc
的方式使得实现仅在 class 定义内有意义 - 但并非完全如此。您收到一个错误,因为 ifunc
的实现就好像它知道您的 class 的内部结构(它指的是私有的),但事实并非如此。您实际上从未将其包含在 class 定义中。所以你必须在 func
中引用私有成员函数 ifunc
并将 ifunc
包含到 class:
func <- function(x) {
if (missing(x) && interactive()) {
private$ifunc()
} else {
private$a <- x * x
}
}
ifunc <- function() {
f <- switch(menu(c('*', '+')), '1'=`*`, '2'=`+`)
private$a <- f(private$a, private$a)
}
Obj <- R6::R6Class(
"Obj",
public=list(
initialize=function(a) private$a <- a,
geta=function() private$a,
func=func # defined in another file
),
private=list(
a=NA,
ifunc=ifunc
)
)
但是,我必须说我不明白这个策略。函数 func
和 ifunc
然后在顶级环境中都有自己的名称但不起作用 - 它们实际上只在 class 定义中才有意义。如果您对代码重用感兴趣,我认为对象组合或继承就不那么令人惊讶了。
首先,让我们把这个例子提炼一下,让它更有说服力:
# function defined outside R6 class
parent_function <- function(x) {
if (missing(x)) {
child_function()
} else {
self$a <- x * x
}
}
# function called by previous function
child_function <- function() {
self$a <- 999999
}
# R6 test object
my_object <- R6::R6Class(
"my_object",
public=list(
func=parent_function,
a=1
)
)
# Testing
tst <- my_object$new()
tst
## <my_object>
## Public:
## a: 1
## clone: function (deep = FALSE)
## func: function (x)
tst$func(8)
tst$a
## [1] 64
tst$func()
## Error in self$a <- 999999 : object 'self' not found
现在的想法是将self
传递给子函数——因为父函数显然可以看到self,所以它可以传递它
# General function defined outside R6 class
parent_function <- function(x) {
if (missing(x)) {
child_function(self)
} else {
self$a <- x * x
}
}
# If interactive, redirect to this function
child_function <- function(self) {
self$a <- 999999
}
# R6 test object
my_object <- R6::R6Class(
"my_object",
public =
list(
func=parent_function,
a=1
),
)
## Testing
tst <- my_object$new()
tst
## <my_object>
## Public:
## a: 1
## clone: function (deep = FALSE)
## func: function (x)
tst$func(8)
tst$a
## [1] 64
tst$func()
tst$a
## [1] 999999
使用 R6 classes 时,在 class 之外定义调用其他方法的方法的正确方法是什么?
考虑以下示例,其中函数 func
如果以交互方式使用,可能会分派给另一个函数。但是,如果这样做,其他功能将无法访问私有环境。如果我以这种方式定义 classes,我应该传递一个环境吗?
## General function defined outside R6 class
func <- function(x) {
if (missing(x) && interactive()) {
ifunc()
} else {
private$a <- x * x
}
}
## If interactive, redirect to this function
ifunc <- function() {
f <- switch(menu(c('*', '+')), '1'=`*`, '2'=`+`)
private$a <- f(private$a, private$a)
}
## R6 test object
Obj <- R6::R6Class("Obj",
public=list(
initialize=function(a) private$a <- a,
geta=function() private$a,
func=func # defined in another file
),
private=list(
a=NA
)
)
## Testing
tst <- Obj$new(5)
tst$func(3)
tst$geta() # so func sees 'private'
# [1] 9
tst$func() # doesn't see 'private'
Error in ifunc() (from #3) : object 'private' not found
您面临的问题是您定义 func
和 ifunc
的方式使得实现仅在 class 定义内有意义 - 但并非完全如此。您收到一个错误,因为 ifunc
的实现就好像它知道您的 class 的内部结构(它指的是私有的),但事实并非如此。您实际上从未将其包含在 class 定义中。所以你必须在 func
中引用私有成员函数 ifunc
并将 ifunc
包含到 class:
func <- function(x) {
if (missing(x) && interactive()) {
private$ifunc()
} else {
private$a <- x * x
}
}
ifunc <- function() {
f <- switch(menu(c('*', '+')), '1'=`*`, '2'=`+`)
private$a <- f(private$a, private$a)
}
Obj <- R6::R6Class(
"Obj",
public=list(
initialize=function(a) private$a <- a,
geta=function() private$a,
func=func # defined in another file
),
private=list(
a=NA,
ifunc=ifunc
)
)
但是,我必须说我不明白这个策略。函数 func
和 ifunc
然后在顶级环境中都有自己的名称但不起作用 - 它们实际上只在 class 定义中才有意义。如果您对代码重用感兴趣,我认为对象组合或继承就不那么令人惊讶了。
首先,让我们把这个例子提炼一下,让它更有说服力:
# function defined outside R6 class
parent_function <- function(x) {
if (missing(x)) {
child_function()
} else {
self$a <- x * x
}
}
# function called by previous function
child_function <- function() {
self$a <- 999999
}
# R6 test object
my_object <- R6::R6Class(
"my_object",
public=list(
func=parent_function,
a=1
)
)
# Testing
tst <- my_object$new()
tst
## <my_object>
## Public:
## a: 1
## clone: function (deep = FALSE)
## func: function (x)
tst$func(8)
tst$a
## [1] 64
tst$func()
## Error in self$a <- 999999 : object 'self' not found
现在的想法是将self
传递给子函数——因为父函数显然可以看到self,所以它可以传递它
# General function defined outside R6 class
parent_function <- function(x) {
if (missing(x)) {
child_function(self)
} else {
self$a <- x * x
}
}
# If interactive, redirect to this function
child_function <- function(self) {
self$a <- 999999
}
# R6 test object
my_object <- R6::R6Class(
"my_object",
public =
list(
func=parent_function,
a=1
),
)
## Testing
tst <- my_object$new()
tst
## <my_object>
## Public:
## a: 1
## clone: function (deep = FALSE)
## func: function (x)
tst$func(8)
tst$a
## [1] 64
tst$func()
tst$a
## [1] 999999