【问题标题】:R: Use active binding in object generator to conditionally add new class to R6 objectsR:在对象生成器中使用活动绑定有条件地向 R6 对象添加新类
【发布时间】:2020-10-29 18:45:25
【问题描述】:

我有一个简单的 R6 对象生成器:

thing <- R6Class("youngThing",
                 private = list(
                   ..age = 0),
                 active = list(
                   age = function(){
                     private$..age <- private$..age + 1
                     private$..age
                   }
                 )
)

这给了我一个简单的 R6 对象,其中 ..age 每次调用活动的 age 字段时都会增加 1:

a_thing <- thing$new()

a_thing$age
# [1] 1

在给定私有字段..age 的阈值的情况下,我希望a_thing 的对象类发生变化,如下所示:

class(a_thing)
# [1] "youngThing" "R6"

for(timestep in 1:10){
  if(a_thing$age >5 & ! inherits(a_thing, "olderThing")){
    class(a_thing) <- c("olderThing", class(a_thing))
  }
}

class(a_thing)
# [1] "olderThing" "youngThing" "R6" 

但是,我希望这发生在对象中。有没有办法在对象生成器中将此作为活动绑定包含在内,以便从它创建的任何对象都内置此功能?

注意。最好将阈值类添加到对象中;它不会取代现有的类。

【问题讨论】:

  • 更改类似乎有点奇怪的设计选择。为什么不只是有一个可以根据需要询问的公共is_old 布尔标志?
  • 我希望有一些答案可以让这在技术上成为可能,但是从设计的角度考虑这意味着什么。如果您将一个对象分配给一个变量,然后调用该方法以使类发生变化,然后调用一个函数,该函数期望具有该对象的旧类。这打破了通常对对象的(不可变)类所做的一些假设,并可能在以后导致问题。
  • @AllanCameron 您好,感谢您的评论。在一个对象是一个人的情况下,我可以使用 S3 泛型方法根据对象(个体)的类别(年龄)来实现不同的方法。
  • @jayb 或者你可以有一个方法来检查年龄字段并做出相应的行为?

标签: r oop inheritance r6


【解决方案1】:

您可以更改self的类。

library(R6)

thing <- R6Class(
  "youngThing",
  private = list(..age = 0),
  active = list(
    age = function() {
      private$..age <- private$..age + 1

      if(private$..age > 5 && !inherits(self, "olderThing")){
        class(self) <- c("olderThing", class(self))
      }
      private$..age
    }
  )
)

a_thing 有它的原始类,而age &lt;= 5

a_thing <- thing$new()

a_thing$age; a_thing$age; a_thing$age; a_thing$age; a_thing$age
#> [1] 2
#> [1] 3
#> [1] 4
#> [1] 5

class(a_thing)
#> [1] "youngThing" "R6" 

然后它会在超过 5 时更新。

a_thing$age
#> [1] 6

class(a_thing)
#> [1] "olderThing" "youngThing" "R6" 

【讨论】:

    猜你喜欢
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    相关资源
    最近更新 更多