2016-10-07 48 views
0

如何更新R6類實例的方法定義?更新R6對象實例中的方法定義

S3使用當前的方法定義,如我所料。 使用R5(引用類)我可以使用myInstance = myInstance $ copy()。 與R6我試着myInstance = myInstance $克隆()但myInstance $ someMethod()仍然調用舊的代碼。

我需要這個,當我從長時間運行的進程創建的轉儲加載對象實例。我想在長時間運行計算後調試並更改對象狀態上的代碼。因此,我不能只創建一個新實例並重新運行初始化。 甚至比R5複製方法(不更新對實例的引用更好)更好,它將是一種將類和當前所有超類的當前定義的行爲(即方法定義)分配給實例的方法。

下面是一個例子:

library(R6) 

Person <- R6Class("Person", 
     lock_objects=FALSE, 
     public = list(
       name = NULL, 
       initialize = function(name = NA, hair = NA) { 
        self$name <- name 
        self$greet() 
       }, 
       greet = function() { 
        cat(paste0("Hello, my name is ", self$name, ".\n")) 
       } 
     ) 
) 

# create an instance 
thomas <- Person$new("Thomas","brown") 

# modify the behaviour of Person 
Person <- R6Class("Person", 
     lock_objects=FALSE, 
     public = list(
       name = NULL, 
       initialize = function(name = NA, hair = NA) { 
        self$name <- name 
        self$greet() 
       }, 
       greet = function() { 
        cat(paste0("Modified greet from ", self$name, ".\n")) 
       } 
     ) 
) 

t1 <- Person$new("t1") # greet function updated 
t2 <- thomas$clone() 
t2$greet()    # greet function not updated in thomas nor t2 
+1

[動態添加函數到r6類實例]的可能重複(https://stackoverflow.com/questions/26331030/dynamically-add-function-to-r6-class-instance) –

回答

0

我想出了下面的技巧。 從問題的代碼繼續,我設法改變的greet方法定義R6對象實例thomas

replacePublicR6Method <- function(r6Instance, fName, fun){ 
    selfEnv <- environment(r6Instance[[fName]])$self 
    properEnv <- environment(r6Instance[[fName]]) 
    unlockBinding(fName, selfEnv) 
    selfEnv[[fName]] <- fun 
    environment(selfEnv[[fName]]) <- properEnv 
    lockBinding(fName, selfEnv) 
} 

replacePublicR6Method(thomas, "greet", function(){ 
      cat(paste0("Modified greetings from ", self$name, ".\n")) 
     }) 

thomas$greet() 

我想結合被鎖定的目的,而這種黑客髒。 向R嚮導提問:這種攻擊可以打破R6類的其他行爲嗎?它會繼續與未來版本的R6類一起工作嗎?

爲了在長時間運行計算之後在對象狀態下進行一些代碼修改,這應該是可以的。到目前爲止,它也適用於子類的實例。