2

我知道这将是一个非常不可靠的黑客攻击。但出于纯粹的兴趣:

.refClassDef如果已实例化对象的引用类定义发生更改并且您希望它“被告知更新”(无需重新实例化它),您需要在 ref 类对象的字段中手动更改什么。

毕竟,如果引入其他方法,它似乎确实有效,但不适用于修改现有方法(参见下面的示例)。

这个问题与我在这篇文章中的回答有关。


例子

原始类定义:

MyReferenceClass <- setRefClass("MyReferenceClass",
    methods = list(
        print_hello = function(){
            print("hello")
        }
    )
)

实例化:

my_object <- MyReferenceClass$new()
my_object$print_hello()
[1] "hello"

更新类定义:

MyReferenceClass <- setRefClass("MyReferenceClass",
    methods = list(
        print_hello = function(){
            print("hello_again")
        },
        print_goodbye = function(){
            print("goodbye")
        }
    )
)

实例可以使用新方法:

my_object$print_goodbye()
[1] "goodbye"

但是,例如,它将无法被告知print_hello如这篇文章所示的变化。

4

1 回答 1

1

在您的类中包含一个update方法(修改前后)。在类的任何更新时调用obj$update()另一个方法之前调用。

MyReferenceClass <- setRefClass(
  "MyReferenceClass",
  methods = list(
    print_hello = function(){
      print("hello")
    },
    update = function(){
      selfEnv <- as.environment(.self)
      .class <- as.character(class(.self))
      for (e in as.vector(utils::lsf.str(selfEnv))){ 
        v <- get(e,eval(parse(text=sprintf("%s@generator$def@refMethods",.class))))
        assign(e,v,envir=selfEnv)
      }
    }
    )
  )

更新:6 月 11 日星期三update方法现在要求更新方法向量,以避免意外更改内部方法。感谢@Rappster 指出这一点。

MyReferenceClass <- setRefClass(
  "MyReferenceClass",
  methods = list(
    print_hello = function(){
      print("hello")
    },
    update = function(x){
      selfEnv <- as.environment(.self)
      .class <- as.character(class(.self))
      for (e in x){
        v <- get(e,eval(parse(text=sprintf("%s@generator$def@refMethods",.class))))
        assign(e,v,envir=selfEnv)
      }
    }
    )
  )

obj <- MyReferenceClass$new()
obj$print_hello()

## ...
obj$update('print_hello')
于 2014-04-03T17:47:54.320 回答