向 R6 子类添加方法
Add methods to an R6 subclass
我开始为工作中的一个项目修补 R6,但我无法理解以下行为。
假设我定义了一个 superclass Person
和一个 subclass PersonWithAge
:
Person <- R6Class("Person",
public = list(
name = NA,
hair = NA,
initialize = function(name, hair) {
if (!missing(name)) self$name <- name
if (!missing(hair)) self$hair <- hair
self$greet()
},
set_hair = function(val) {
self$hair <- val
},
greet = function() {
cat(paste0("Hello, my name is ", self$name, ".\n"))
}
)
)
PersonWithAge <- R6Class("PersonWithAge",
inherit = Person,
public = list(
age = NA))
如果我尝试向子class PersonWithAge
添加新方法,我会收到以下错误:
> PersonWithAge$set("public", "set_age", function(age) self$age <<- age)
Error in self[[group]][[name]] <- value :
invalid type/length (closure/0) in vector allocation
现在,如果我用虚拟方法定义一个新的 subclass,我可以毫无问题地向 subclass 添加新方法:
PersonWithHeight <- R6Class("PersonWithHeight",
inherit = Person,
public = list(
height = NA,
foo = function() print(1)
))
PersonWithHeight$set("public", "set_height", function(height) self$height <<- height)
> caitlin <- PersonWithHeight$new("Caitlin", "auburn")
Hello, my name is Caitlin.
> caitlin$set_height(165)
> caitlin
<PersonWithHeight>
Public:
foo: function
greet: function
hair: auburn
height: 165
initialize: function
name: Caitlin
set_hair: function
set_height: function
我尝试更改 R6Class
class 定义中的 lock
参数但无济于事。会话信息是:
> sessionInfo()
R version 3.1.1 (2014-07-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=French_France.1252 LC_CTYPE=French_France.1252 LC_MONETARY=French_France.1252 LC_NUMERIC=C
[5] LC_TIME=French_France.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] R6_2.0.1
loaded via a namespace (and not attached):
[1] tools_3.1.1
我在另一台机器上使用此会话信息也得到了相同的行为:
> sessionInfo()
R version 3.1.2 (2014-10-31)
Platform: x86_64-pc-linux-gnu (64-bit)
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=C LC_COLLATE=C LC_MONETARY=C LC_MESSAGES=C
[7] LC_PAPER=C LC_NAME=C LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=C LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] R6_2.0.1
loaded via a namespace (and not attached):
[1] tools_3.1.2
我的问题如下:
- 我是不是遗漏了什么或者这是正常的和预期的行为?既然如此,为什么会这样?
- 只要我在这里 : 据我了解,R6 中没有虚拟 classes 和抽象方法的真正实现?
编辑: 好的,在查看包的源代码后,我意识到,在这一行中:
self[[group]][[name]] <- value
group
是 public_methods
、private_methods
、public_fields
、private_fields
之一。所以我猜想当 class 在没有任何 public 方法的情况下创建时,向 class 添加新的 public 方法会失败,因为该组实际上并不存在。
我设法通过从 Winston Chang 的回购中提取源代码并修改 utils.R
中的 get_functions
和 get_nonfunctions
函数来解决这个问题,以便它们 return一个空列表而不是 NULL
当没有找到函数(resp. 没有非函数)时。
我开始为工作中的一个项目修补 R6,但我无法理解以下行为。
假设我定义了一个 superclass Person
和一个 subclass PersonWithAge
:
Person <- R6Class("Person",
public = list(
name = NA,
hair = NA,
initialize = function(name, hair) {
if (!missing(name)) self$name <- name
if (!missing(hair)) self$hair <- hair
self$greet()
},
set_hair = function(val) {
self$hair <- val
},
greet = function() {
cat(paste0("Hello, my name is ", self$name, ".\n"))
}
)
)
PersonWithAge <- R6Class("PersonWithAge",
inherit = Person,
public = list(
age = NA))
如果我尝试向子class PersonWithAge
添加新方法,我会收到以下错误:
> PersonWithAge$set("public", "set_age", function(age) self$age <<- age)
Error in self[[group]][[name]] <- value :
invalid type/length (closure/0) in vector allocation
现在,如果我用虚拟方法定义一个新的 subclass,我可以毫无问题地向 subclass 添加新方法:
PersonWithHeight <- R6Class("PersonWithHeight",
inherit = Person,
public = list(
height = NA,
foo = function() print(1)
))
PersonWithHeight$set("public", "set_height", function(height) self$height <<- height)
> caitlin <- PersonWithHeight$new("Caitlin", "auburn")
Hello, my name is Caitlin.
> caitlin$set_height(165)
> caitlin
<PersonWithHeight>
Public:
foo: function
greet: function
hair: auburn
height: 165
initialize: function
name: Caitlin
set_hair: function
set_height: function
我尝试更改 R6Class
class 定义中的 lock
参数但无济于事。会话信息是:
> sessionInfo()
R version 3.1.1 (2014-07-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=French_France.1252 LC_CTYPE=French_France.1252 LC_MONETARY=French_France.1252 LC_NUMERIC=C
[5] LC_TIME=French_France.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] R6_2.0.1
loaded via a namespace (and not attached):
[1] tools_3.1.1
我在另一台机器上使用此会话信息也得到了相同的行为:
> sessionInfo()
R version 3.1.2 (2014-10-31)
Platform: x86_64-pc-linux-gnu (64-bit)
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=C LC_COLLATE=C LC_MONETARY=C LC_MESSAGES=C
[7] LC_PAPER=C LC_NAME=C LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=C LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] R6_2.0.1
loaded via a namespace (and not attached):
[1] tools_3.1.2
我的问题如下:
- 我是不是遗漏了什么或者这是正常的和预期的行为?既然如此,为什么会这样?
- 只要我在这里 : 据我了解,R6 中没有虚拟 classes 和抽象方法的真正实现?
编辑: 好的,在查看包的源代码后,我意识到,在这一行中:
self[[group]][[name]] <- value
group
是 public_methods
、private_methods
、public_fields
、private_fields
之一。所以我猜想当 class 在没有任何 public 方法的情况下创建时,向 class 添加新的 public 方法会失败,因为该组实际上并不存在。
我设法通过从 Winston Chang 的回购中提取源代码并修改 utils.R
中的 get_functions
和 get_nonfunctions
函数来解决这个问题,以便它们 return一个空列表而不是 NULL
当没有找到函数(resp. 没有非函数)时。